A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function below:

async function - JavaScript | MDN

async function 宣言は、AsyncFunction オブジェクトを作成します。非同期関数が呼び出されるたびに、新しいプロミス (Promise) が返され、非同期関数によって返された値で解決されます。または、非同期関数内で捕捉されなかった例外で拒否されます。

非同期関数には、 await 式を置くことができます。 await 式は返されたプロミスが履行されるか拒否されるまで実行を中断することで、プロミスを返す関数をあたかも同期しているかのように動作させます。プロミスの解決済みの値は、await 式の返値として扱われます。async と await を使用すると、非同期コードに通常の try / catch ブロックを使用することができます。

メモ: キーワード await は、通常の JavaScript コード内の非同期関数内でのみ有効です。非同期関数の外で使用した場合は SyntaxError が発生します。

await は JavaScript モジュールでは単独で使用することができます。

メモ: async/await の目的は、プロミスベースの API を利用するのに必要な構文を簡素化することです。 async/await の動作は、ジェネレーターとプロミスの組み合わせに似ています。

非同期関数は常にプロミスを返します。非同期関数の返値が明示的にプロミスでない場合は、暗黙的にプロミスでラップされます。

例えば、以下のコードを考えてください。

async function foo() {
  return 1;
}

これは、次のコードに似ています。

function foo() {
  return Promise.resolve(1);
}

たとえ非同期関数の返値が Promise.resolve でラップされているかのように振る舞うとしても、それらは同等ではないことに注意してください。非同期関数は別の参照を返しますが、Promise.resolve は指定された値がプロミスであれば同じ参照を返します。プロミスと非同期関数の返値の等価性を調べようとすると、問題が発生する可能性があります。

const p = new Promise((res, rej) => {
  res(1);
});

async function asyncReturn() {
  return p;
}

function basicReturn() {
  return Promise.resolve(p);
}

console.log(p === basicReturn()); // true
console.log(p === asyncReturn()); // false

非同期関数の本体は、0 個以上の await 式で分割されていると考えることができます。最上位のコードは、最初の await 式(ある場合)まで含めて同期的に実行されます。この方法では、await 式のない非同期関数は同期的に実行されます。しかし、関数本体内に await 式がある場合、非同期関数は常に非同期的に完了します。

例:

async function foo() {
  await 1;
}

これは次のものと等価です。

function foo() {
  return Promise.resolve(1).then(() => undefined);
}

それぞれの await 式の後のコードは、.then コールバックの中に存在すると考えることができます。このようにして、関数を再帰的に実行するたびに、プロミスチェーンが徐々に構築されていきます。返値はチェーンの最後のリンクになります。

次の例では、 2 つのプロミスを連続して待ち受けます。関数 foo の処理は 3 段階に分かれています。

  1. 関数 foo の本体の最初の行は、保留中のプロミスで await 式が構成された状態で、同期的に実行されます。その後、foo の処理は中断され、foo を呼び出した関数に制御が返されます。
  2. しばらくして、最初のプロミスが履行されるか拒否されると、制御は foo に戻ります。(拒否されなかった場合は)最初のプロミスが履行された結果が await 式から返されます。ここでは 1 が result1 に代入されます。処理は続き、2 つ目の await 式が評価されます。このときも foo の処理が中断され、制御が移譲されます。
  3. しばらくして、2 つ目のプロミスが履行されたか拒否されたとき、制御は foo に再び入ります。2 つ目のプロミスが解決した結果が 2 番目の await 式から返されます。ここでは 2 が result2 に代入されます。制御は(もしあれば)return 式に移ります。既定の返値である undefined が、現在のプロミスの解決値として返されます。
async function foo() {
  const result1 = await new Promise((resolve) =>
    setTimeout(() => resolve("1")),
  );
  const result2 = await new Promise((resolve) =>
    setTimeout(() => resolve("2")),
  );
}
foo();

プロミスチェーンが一度に構築されないことに注意してください。プロミスチェーンは、非同期関数に制御を渡したり戻したりしながら、段階的に構築されていきます。そのため、同時並行の非同期処理を行う際には、エラー処理の動作に注意しなければなりません。

例えば、以下のコードでは、プロミスチェーンの先に .catch ハンドラーが設定されていたとしても、未処理のプロミス拒否エラーが発生します。これは、p1 から制御が戻るまで、p2 がプロミスチェーンに「配線」されないためです。

async function foo() {
  const p1 = new Promise((resolve) => setTimeout(() => resolve("1"), 1000));
  const p2 = new Promise((_, reject) => setTimeout(() => reject("2"), 500));
  const results = [await p1, await p2]; // こうしないでください。 Promise.all または Promise.allSettled を使用してください。
}
foo().catch(() => {}); // すべてのエラーを浅くしようとする...

async function 宣言は、function 宣言と似た挙動をします。つまり、巻き上げによりスコープの先頭に移動し、スコープ内のどこからでも呼び出すことができます。また、特定のコンテキストでのみ再宣言することができます。


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4