トップレベル await
トップレベル await は、ES2022 で導入された機能で、モジュールの最上位で直接 await を使用できます。async 関数で囲む必要がなくなり、非同期の初期化処理が簡潔に書けるようになりました。
基本的な使い方
モジュールのトップレベルで await を使用できます。
// config.js
const response = await fetch('/api/config');
export const config = await response.json();
console.log('設定を読み込みました');// main.js
import { config } from './config.js';
// config.js の await が完了してからここが実行される
console.log(config);以前の書き方との比較
トップレベル await がない場合
// 即時実行の async 関数が必要
let config;
(async () => {
const res = await fetch('/api/config');
config = await res.json();
})();
export { config };トップレベル await がある場合
const res = await fetch('/api/config');
export const config = await res.json();コードがシンプルになり、エクスポートする値が確実に初期化された状態になります。
実用的な使用例
// database.js
import { createConnection } from 'database-lib';
// データベース接続を確立してからエクスポート
export const db = await createConnection({
host: 'localhost',
database: 'myapp'
});
console.log('データベースに接続しました');// i18n.js
const locale = navigator.language || 'en';
const response = await fetch(`/locales/${locale}.json`);
export const messages = await response.json();依存モジュールへの影響
トップレベル await を使用するモジュールをインポートすると、そのモジュールの await が完了するまで、インポート元のモジュールの実行も待機します。
// slow.js
await new Promise(resolve => setTimeout(resolve, 2000));
export const data = 'loaded';
console.log('slow.js 完了');// main.js
console.log('main.js 開始');
import { data } from './slow.js';
console.log('main.js 完了'); // slow.js の await 後に実行される出力順序は以下のようになります。
main.js 開始
(2秒待機)
slow.js 完了
main.js 完了
並列読み込み
複数の非同期処理を並列で実行したい場合は、Promise.all を使います。
// data.js
const [users, products, orders] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/products').then(r => r.json()),
fetch('/api/orders').then(r => r.json())
]);
export { users, products, orders };エラーハンドリング
トップレベル await でエラーが発生すると、モジュールの読み込み自体が失敗します。
// config.js
try {
const response = await fetch('/api/config');
if (!response.ok) {
throw new Error('設定の取得に失敗');
}
export const config = await response.json();
} catch (error) {
console.error('初期化エラー:', error);
export const config = { fallback: true };
}注意点
パフォーマンスへの影響
トップレベル await は、依存するすべてのモジュールの読み込みをブロックします。不必要な待機を避けるよう設計してください。
ブラウザサポート
モダンブラウザではサポートされていますが、古いブラウザや一部の環境では使用できません。
import() の中でも使用可能トップレベル await を活用することで、モジュールの初期化処理をより直感的に記述できます。