JavaScript 事件函数 - 在声明之前调用

javascript event functions - called before being declared

本文关键字:调用 声明 事件 函数 JavaScript      更新时间:2023-09-26

我有一个关于JavaScript函数的问题。

作为示例,请参考下面的代码。

  • 在前 2 行中,我打开了一个索引数据库。
  • 之后,我将 onsuccess 函数附加到 openRequest。
  • 警报正确显示。

我假设"打开"函数触发"成功"事件函数。但是,由于"成功"函数在调用"open"函数附加到openRequest,这如何工作呢?

var indexedDB = window.indexedDB;
var openRequest = indexedDB.open('MyTestDB');
openRequest.onsuccess = function (response) {
    alert('sucess');
};

indexDB.open的调用是异步的。它会立即返回,其余代码继续运行。当数据库实际打开时,将触发一个事件。此事件放置在事件队列中。JavaScript 解释器定期检查事件队列。但解释器也是单线程的。它不会跳出它正在执行的当前代码来检查它。在定义 onsuccess 函数之前,永远不会调用它。事实上,数据库本身也永远不会被打开,直到以后。

例如,如果在代码末尾放置一个无尽的 while 循环,则永远不会运行 onsucess 函数。

var indexedDB = window.indexedDB;
var openRequest = indexedDB.open('MyTestDB');
openRequest.onsuccess = function (response) {
    alert('sucess');
};
while (true) {};

此时将阻止执行,解释器永远不会检查事件队列,也永远不会运行成功函数。

http://javascript.info/tutorial/events-and-timing-depth

这是可能的,因为JavaScript VM(以V8为例)执行成功处理程序的分配速度比打开indexDB的速度快。这是由于对indexedDB.open()的调用是异步的,因此 VM 在后台打开数据库执行事件处理程序分配。

如果延迟事件处理程序的分配,您将看到它不再被调用:

→ 小提琴

var indexedDB = window.indexedDB;
var openRequest = indexedDB.open('MyTestDB');
window.setTimeout(function () {
    openRequest.onsuccess = function (response) {
        alert('sucess');
    };
}, 1); // also test higher values - 1ms worked fine for me

另请阅读上面的艾切迪的回答!

indexedDB.open

后台发出异步请求。准备就绪后,将调用onsuccess事件侦听器。

更好的做法是在 indexedDB.open 之前设置事件处理程序。