Top-level await
Top-level await (TC39 Stage 4, ES2022) позволяет использовать await на верхнем уровне ESM-модуля — импортирующий модуль неявно ожидает завершения, что меняет граф загрузки и важно понимать при бандлинге и серверном рендеринге.
// ДО TLA: экспорт промиса или init-функции — неудобно// export const dbPromise = connectToDatabase();
// ПОСЛЕ: top-level await — db уже готов при импортеconst db = await connectToDatabase(); // блокирует загрузку модуляexport { db };
// Использование в app.mjs:import { db } from './db.mjs';// Гарантировано: db инициализирован до начала выполнения app.mjsconsole.log(db.status); // 'connected'// Граф зависимостей при TLAexport const config = await fetch('/config').then(r => r.json());
// b.mjs импортирует a.mjs → b ЖДЁТ пока a завершит TLAimport { config } from './a.mjs';console.log(config.version); // уже доступен
// Параллельная загрузка независимых модулей:// e.mjs импортирует и c.mjs и d.mjs (оба с TLA)// import './c.mjs'; import './d.mjs';// → TLA в c и d выполняются параллельно (как Promise.all)// → e ждёт завершения обоих// Практика: conditional polyfill / feature detectionconst { default: nodeFetch } = await ( typeof globalThis.fetch === 'undefined' ? import('node-fetch') : { default: globalThis.fetch });
// Dynamic config с fallbackconst config = await (async () => { try { return (await import('./config.local.json', { assert: { type: 'json' } })).default; } catch { return (await import('./config.default.json', { assert: { type: 'json' } })).default; }})();
// TLA работает только в .mjs или "type": "module"// В .cjs → SyntaxErrorИтог: Top-level await превращает ESM-модуль в асинхронный участник графа зависимостей; все импортирующие его модули неявно ожидают завершения TLA, а параллельные TLA-модули выполняются параллельно.