Get to know MDN better
このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docs コミュニティーについてもっと知り、仲間になるにはこちらから。
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2017年3月.
* Some parts of this feature may have varying levels of support.
await 演算子はプロミス (Promise) を待ち、履行値を取得するために使用します。非同期関数の中、またはモジュールの最上位でのみ使用することができます。
待つ Promise、thenable、または何らかの値です。
プロミスまたは thenable オブジェクトの履行値、または式が thenable でない場合は、式自身の値。
プロミスまたは thenable オブジェクトが拒否された場合、拒否理由の例外が発生します。
通常、await は Promise を expression として渡して、プロミスをアンラップするために使用します。await を用いると、プロミスが決定(つまり、履行または拒否)されるまで、その周囲にある async 関数の実行が一時的に停止されます。実行が再開されると、await式の値は履行されたプロミスの値になります。
プロミスが拒否された場合、await 式は拒否された値で例外を発生します。await 式を格納した関数は、エラーのスタックトレースに表示されます。それ以外の場合、拒否されたプロミスが待機されなかったり、すぐに返されたりすると、呼び出し側の関数はスタックトレースに現れません。
expression は Promise.resolve() と同じように解決されます。常に ネイティブの Promise に変換され、待ち受けされます。もし expression が以下の場合、
用いたプロミスが既に履行された場合でも、非同期関数の実行は次のティックまで一時停止します。その間に、非同期関数の呼び出し側が実行を再開します。下記の例をご覧ください。
await は非同期関数やモジュールの内部でのみ有効であり、それ自体が非同期で、プロミスを返すので、await 式はメインスレッドをブロックすることはなく、実際に結果に依存するコード、つまり await 式の後に実行を延期するだけです。
Promise が await 式に渡された場合、 Promise が履行されて履行値を返すのを待ちます。
Thenable オブジェクト は同様に履行されます。
これは同様に拒否されます。
値が Promise でない場合、 await は値を解決された Promise に変換し、それを待ちます。待ち受ける値に関しては、呼び出し可能な then プロパティがない限り、そのアイデンティティは変わりません。
Promise が拒否された場合、拒否された値で例外が発生します。
プロミスを待つ前に catch() ハンドラーを連結すれば、try ブロックなしで拒否されたプロミスを処理することができます。
これは、promisedFunction() が同期的にエラーを発生させることはなく、常に拒否されたプロミスを返すという前提で作られています。これは、適切に設計されたプロミスベースの関数のほとんどがそうであり、通常は次のようになります。
しかし、promisedFunction() が同期的にエラーを発生した場合、そのエラーは catch() ハンドラーによって捕捉されません。この場合、try...catch 文が必要になります。
await キーワードは、モジュールの最上位は単独で(非同期関数の外で)使用することができます。つまり、 await を使う子モジュールを持つモジュールは、子モジュールが実行されるのを待ってから、自分自身が実行されるようになります。他の子モジュールの読み込みをブロックすることなく、実行することができます。
以下は、 Fetch API を使用し、 export 文の中で await を指定したモジュールの例です。これを含むすべてのモジュールは、コードを実行する前に読み取りが解決するのを待ちます。
コード(非同期関数またはモジュール内)で await に出会うと、 await の対象となる式が実行され、その式の値に依存するすべてのコードは一時停止されます。制御は関数を終了し、呼び出し側に戻ります。待機中の式の値が解決されると、一時停止したコードを続ける別の マイクロタスクがスケジュールされます。これは、待機中の値がすでに解決済みのプロミスであったり、プロミスではなかったりする場合でも行われます。実行は、スケジュール済みの他のすべてのマイクロタスクが処理されるまで、現在の関数に戻りません。例えば、次のコードを考えてみましょう。
この場合、関数 foo は、await 式が含まれていないため、効果は同期的です。 3 つの文は同じ刻みで実行されます。したがって、 2 つの関数呼び出しは、すべての文を順番に実行します。プロミスの場合、この関数は次のように表されます。
しかし、await が 1 つでもあると、その関数は非同期となり、以降の文の実行は次のティックまで延期されます。
これは次のものに相当します。
余分な then() ハンドラーは、非同期操作を待機しないため、コンストラクターに渡された実行者と統合することができます。ただし、このハンドラーが存在すると、 foo が呼び出されるたびにコードが 1 つのマイクロタスクに分割されます。これらのマイクロタスクは、相互に絡み合ってスケジュールされ、実行されます。これにより、コードの速度が低下したり、不要なレースコンディションが発生したりする可能性があります。したがって、 await は必要な場合(プロミスをその値にラップ解除する場合)にのみ使用してください。
マイクロタスクは、プロミスの解決だけでなく、それ以外のウェブ API によってもスケジュールされ、同じ優先度で実行されます。この例では、 queueMicrotask() を使用して、各 await 式が検出されたときにマイクロタスクキューがどのように処理されるかを示しています。
この例では、非同期関数が再開される前に常に test() 関数が呼び出されるので、それぞれがスケジュールするマイクロタスクは常に絡み合うように実行されます。一方、await と queueMicrotask() はどちらもマイクロタスクをスケジュールするので、実行順序は常にスケジューリングの順序に基づきます。このため、"queueMicrotask() after calling async function" のログ出力は、非同期関数が最初の時刻に再開した後に行われます。
非同期関数からプロミスを直接返す場合、await が省略されることがあります。
しかし、lastAsyncTask にて非同期にエラーが発生する場合を考えてみましょう。
スタックトレースには lastAsyncTask だけが現れますが、これはプロミスが noAwait から既に返された後に拒否されたためです。ある意味、プロミスは noAwait と無関係と言えます。スタックトレースを改善するには、await を使用してプロミスをアンラップし、例外が現在の関数に使用されるようにすることができます。例外はすぐに新しい拒否されたプロミスにラップされますが、エラー作成中に呼び出し側がスタックトレースに現れます。
一般的な認識に反して、 return await promise は、仕様とエンジンがネイティブプロミスの解決を最適化するため、 return promise と同等以上の速度です。 return promise の高速化の提案があり、V8 の async 関数の最適化についても読むことができます。したがって、コーディングスタイル上の理由がない限り、 return await を常に推奨します。
| ECMAScript® 2027 Language Specification # sec-async-function-definitions |
Enable JavaScript to view this browser compatibility table.
This page was last modified on 2026年4月1日 by MDN contributors.
Your blueprint for a better internet.
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998–2026 by individual mozilla.org contributors. Content available under a Creative Commons license.