new must return an object synchronously, so async constructor() is a SyntaxError. Returning an async IIFE from the constructor works, but then new yields a Promise, not an instance. Use a static async factory that awaits the slow work and then calls a cheap constructor; a private static key stops callers from bypassing it.
class Db {
static #key = Symbol(); // only code inside Db can see it
constructor(conn, key) {
if (key !== Db.#key) throw new TypeError('Use Db.open()');
this.conn = conn;
}
static async open(url) { // async factory
return new Db(await new Promise((ok) => setTimeout(ok, 20, `connected: ${url}`)), Db.#key);
}
}
const db = await Db.open('db://local');
console.log(db.conn, db instanceof Db);
try { new Db(); } catch (e) { console.log(e.message); }connected: db://local true Use Db.open()