IndexedDB 模块中的顶级await阻止`onload`触发

nkoocmlb  于 8个月前  发布在  IndexedDB
关注(0)|答案(1)|浏览(159)

我看到,如果我在间接加载的模块的顶层为IndexedDB打开awaitload事件将不会触发。
如果我删除了awaitload处理程序将按预期被调用。如果我保留了await,但用一个伪promise(如Promise.resolve(42))替换openDB调用,load处理程序将按预期被调用。
这是怎么回事,我如何调试它?
index.html:

...
<script type="module" src="js/ui_index.js" type="javascript/module"></script>
...

字符串
(it还包含一个importmap,因此所有导入都可以正常工作)
ui_index.js:

import * as db from "database";
...
window.addEventListener('load', () => console.log('onload'));
console.log('ui');


database.js:

import { openDB } from "lib/idb";

//         ↓↓↓↓↓ *** THIS AWAIT ***
const db = await openDB("my-database-name", 4, {

    upgrade(db, old_ver, new_ver, tx) {
        console.log(`db.upgrade ${old_ver}→${new_ver}`);
    }
}

console.log('db:', db);


上面的idb模块是一个promises-based IndexedDB wrapper by Jake Archibald
await的控制台输出:

db.upgrade 4→5
db: Proxy { <target>: IDBDatabase, <handler>: {…} }
ui


不带await的控制台输出:

db: Promise { <state>: "pending" }
ui
onload
db.upgrade 5→6


(The当然,db.upgrade行只有在openDB调用中增加DB版本时才会出现。它不会影响onload行为)。
我在Firefox 120中测试了这一点,还没有尝试过其他浏览器;我正在构建一个内部使用的小型Web应用程序,该应用程序仅适用于Firefox。

rbl8hiat

rbl8hiat1#

我的猜测是,你在脚本体中做等待,而不是声明一个函数来做等待,这推迟了onload事件侦听器的附加,我相信它仍然被触发,但在你的事件侦听器被附加之前。
我可以向你推荐这样的东西吗:
database.js:

import { openDB } from "lib/idb";

export default async function open() {
        const db = await openDB("my-database-name", 4, {
            upgrade(db, old_ver, new_ver, tx) {
                console.log(`db.upgrade ${old_ver}→${new_ver}`);
            }
        }
        console.log('db:', db);
}

字符串
ui_index.js:

import open from "database";
window.addEventListener('load', () => console.log('onload'));
console.log('ui');
open();

相关问题