此时发送 IndexedDB 请求或事务

At which point is an IndexedDB request or transaction sent

来自提供的示例 here and here

他们展示了创建请求,然后在发出请求后附加 onerroronsuccess 处理程序。

var transaction = db.transaction(["customers"], "readwrite");

// Do something when all the data is added to the database.
transaction.oncomplete = function(event) {
    alert("All done!");
};

transaction.onerror = function(event) {
    // Don't forget to handle errors!
};

var objectStore = transaction.objectStore("customers");
    for (var i in customerData) {
        var request = objectStore.add(customerData[i]);
       request.onsuccess = function(event) {
           // event.target.result == customerData[i].ssn;
       };
}

所以我的问题是,请求是在哪一点发送的。 会不会是如果请求足够快,处理程序就不会被附加,因此不会触发。

我很惊讶他们没有写 JQuery get request 是如何设置的,通过它在请求的创建中声明所有处理程序。

Could it be that if the request is quick enough would the handlers not be attached and therefore not trigger

不,您不必担心。该事件已排队,仅当控件 returns 下次编写脚本时才会触发,此时您的处理程序将被分配。

如果我理解了您的问题,那么为了让您开始理解答案,您需要了解或回顾异步 javascript。如果你已经知道这些东西,抱歉,但在我看来,如果你知道这些,你会很容易回答你自己的问题。

经典训练说在下面的代码中,第二个语句出现在第一个语句之后,在稍后的时间:

var x = 1;
var y = 2;
console.log('%s %s', x, y);

然而,这实际上是对真实情况的简化。本质上,Javascript引擎中有一个隐藏的过程,叫做事件循环。循环中的每次迭代都执行一系列语句。这些语句串行执行(按顺序),技术上执行时间略有不同。

但是,从并发的角度来看,它们是同时发生的。在事件循环的特定传递中多个语句的这种同时出现可以称为纪元或时间段,或类似的东西。这本质上也可以理解为同步代码。

异步代码的工作方式完全不同。本质上,当您发起对异步函数的调用时,您并不是在等待该函数 returns。同一时期(如上所述)内的其余代码(后面的语句)也将被执行。函数调用最终会完成,但这只会发生在稍后的时期(事件循环的下一次传递,或之后的一些传递)。

让我们大致了解异步工作的方式:

var x, y;
setTimeout(function eventuallyRunMe() {
 x = 1;
 y = 2;
}, 1);
console.log('%s %s', x, y);

在第一个纪元中,变量被声明,它们没有被赋值,并且执行了对 setTimeout 的调用。 然后,一个epoch结束,下一个epoch开始。 JS 引擎检查是否已经过了 1 秒。让我们假设它确实如此。 Then,JS引擎从头到尾调用eventuallyRunMe。该函数在外部范围内为 x 和 y 赋值。然后,对于第二个纪元的剩余时间以及所有未来的纪元,x 和 y 都有值。

因此,如果您要 运行 此代码,那么在同步示例中,您会看到 x 和 y 的值打印到控制台。在异步示例中,您会看到未定义。这是因为对 console.log 的调用与同步示例中的声明和赋值发生在同一时期,但与异步示例中的分配不在同一时期。

现在,看看您的示例中的代码:

var transaction = db.transaction(...);
transaction.oncomplete = function() {};
transaction.onerror = function() {};

正如您所注意到的,无论这些语句的顺序如何,代码都能正常工作。那是对的。这些语句是关联的。顺序并不重要。那是因为这些语句只是异步回调的同步注册。对 db.transaction 的调用实际上并没有立即在同一个时期打开交易。它会立即创建一个变量来引用事务,并且会立即创建一个事务对象,但它不一定会启动 运行 事务的 put/get/openCursor 请求。什么都不会立即发生。只有在纪元的最后,一切才开始发生。在 epoch 的末尾(或下一个 epoch 的开始,无论你认为什么更容易理解),底层 JS 引擎返回并查看注册要执行的内容,然后几乎同时执行所有内容。然后 JS 事件循环的下一个 epoch 开始,如果此时调用已完成,则调用回调函数等。

这是对事情的简化,而且是非正式的,我相信专家想要更准确的解释,但我希望这有助于让您了解顺序并不重要。