IndexedDB事件监听器为何在open操作后而非之前赋值?
关于IndexedDB open操作后设置事件监听器的疑问
示例代码
let db; // Let us open our database const DBOpenRequest = window.indexedDB.open("toDoList", 4); // these event handlers act on the database being opened. DBOpenRequest.onerror = (event) => { note.innerHTML += "<li>Error loading database.</li>"; }; DBOpenRequest.onsuccess = (event) => { note.innerHTML += "<li>Database initialized.</li>"; };
问题
我理解DBOpenRequest.onerror = xxx是设置处理error事件的监听器。但为何要在触发事件的语句(即const DBOpenRequest = window.indexedDB.open这个open操作)执行后,而非之前设置事件处理器?会不会出现open操作执行后、设置error事件处理器前,事件就已触发,导致没有任何监听器能捕获该事件的情况?
解答
这种写法是安全的,不会出现你担心的事件丢失问题,核心原因在于IndexedDB的异步执行机制:
- 调用
window.indexedDB.open()时,浏览器只是启动了数据库打开的异步任务,这个任务不会立刻执行,而是被放入浏览器的宏任务队列等待调度。 - 当前上下文的同步代码(包括后续绑定
onerror、onsuccess监听器的代码)会被优先执行完毕,之后浏览器才会处理队列中的异步任务。 - 这意味着数据库打开的结果(成功或失败)只会在所有同步代码执行完成后才触发对应事件,此时你的监听器已经设置完成,完全可以捕获到事件。
另外补充一点:你没法做到“先设置监听器再执行open”——因为IDBOpenDBRequest对象是open()方法的返回值,必须先调用open()拿到这个对象,才能为它绑定事件监听器。所以这种“先调用open,再绑监听器”的写法是唯一可行的方式,且本身就不存在事件丢失的风险。
内容的提问来源于stack exchange,提问作者Name Null
相关产品推荐
相关产品推荐

