模块中的顶级等待会阻止`onload`触发

问题描述 投票:0回答:1

我发现,如果我

load
在间接加载模块的顶层打开 IndexedDB,则
await
事件不会触发。

如果我删除

await
,则会按预期调用
load
处理程序。 如果我保留
await
但用虚拟承诺替换
openDB
调用(如
Promise.resolve(42)
),则将按预期调用
load
处理程序。

发生了什么事,我该如何调试?

index.html:

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

(它还包含一个导入映射,因此所有导入都可以正常工作)

ui_index.js:

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

数据库.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
模块是 Jake Archibald 开发的基于 promises 的 IndexedDB 包装器。

控制台输出带有

await
:

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

控制台输出没有

await
:

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

(当然,仅当我在

db.upgrade
调用中增加数据库版本时,
openDB
行才会出现。它不会影响
onload
行为)。

我正在 Firefox 120 中测试此功能,尚未尝试其他浏览器;我正在构建一个供内部使用的小型网络应用程序,该应用程序只能与 Firefox 一起使用。

javascript firefox async-await indexeddb
1个回答
0
投票

我的猜测是,您在脚本主体中执行等待,而不是声明执行等待的函数,这推迟了 onload 事件侦听器的附加,我相信它仍然会被触发,但在附加事件侦听器之前。

我可以建议你这样的事情吗:

数据库.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();
© www.soinside.com 2019 - 2024. All rights reserved.