I'm seeing that the load
event won't fire if I await
for an IndexedDB opening at the top level in an indirectly loaded module.
If I remove the await
, the load
handler is called as expected.
If I keep the await
but replace the openDB
call with a dummy promise (like Promise.resolve(42)
), the load
handler is called as expected.
What is going on, and how can I debug this?
index.html:
...
<script type="module" src="js/ui_index.js" type="javascript/module"></script>
...
(it also contains an importmap, so all the imports work correctly)
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);
The idb
module above is a promises-based IndexedDB wrapper by Jake Archibald.
Console output with await
:
db.upgrade 4→5
db: Proxy { <target>: IDBDatabase, <handler>: {…} }
ui
Console output without await
:
db: Promise { <state>: "pending" }
ui
onload
db.upgrade 5→6
(The db.upgrade
line, of course, is only present if I increment the DB version in the openDB
call. It does not affect the onload
behavior).
I am testing this in Firefox 120 and have not tried other browsers; I'm building a small web app for in-house use which will only be used with Firefox.
My guess is that you do the await in the script body instead of declaring a function that does the await, this postponed the attaching of onload event listener, I believe it is still fired but before your event listener is attached.
May I suggest you something like this:
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();