トップページに戻る

Javascript 非同期関数とPromiseオブジェクト

JavascriptはWebアプリで使われるという特徴から、ネットワーク通信を行う場合があります。

  1. async 関数を呼び出した直後の動作
    非同期関数 afunc() を呼び出すと、関数内の処理が実行される前に、Promise オブジェクトが即座に返される
    ・ このため、afunc() の実行が完了するのを待たずに、次の処理に進むことができる。
    ・ async関数のreturn値は、awaitで取得できる。
    ・ 一方で、
    例:
    async function afunc() {
      console.log("処理開始");
      await new Promise(resolve => setTimeout(resolve, 1000)); // 1秒待機
      console.log("処理終了");
      return "結果";
    }
    const promise = afunc(); // ここで Promise が即座に返される
    console.log(promise); // 出力: Promise { <pending> }
    const result = await afunc(); // 成功した場合はreturn値をうけとる。失敗した場合は例外を出すので、try~catchで処理する
    console.log(result); // 出力: "結果"

    awaitの例外処理:
    async function afunc() {
      throw new Error("エラーが発生しました"); // 明示的にエラーをスロー
    }
     
    async function main() {
      try {
        const result = await afunc(); // エラーがスローされる
        console.log(result);
      } catch (error) {
        console.error("捕捉したエラー:", error.message); // 出力: "捕捉したエラー: エラーが発生しました"
      }
    }
       
  2. メソッドチェーン: Promiseの状態や値を利用する唯一の方法
    Promise オブジェクトの状態や結果を直接確認できないので、then/catchで値を取得する。
    例:
    const promise = afunc();
    promise
      .then(value => console.log("成功:", value)) // 成功した場合の処理。valueにはreturn値が入る
      .catch(error => console.log("失敗:", error)); // エラー時の処理。errにはasync関数内部でthrowされたエラーやPromise.refect()などのエラー情報です
     
  3. 非同期関数を同期関数として利用する
    ・ awaitで終了を待つ
    ・ awaitはasync関数内部でしか使えない
    ・ 関数内部で全ての処理を終える場合は、その関数はasync関数でなくてもよい
      
  4. Promiseは、async 関数内部の処理が終了し、値を返したり、エラーをスローする準備ができるまで「未解決(pending)」の状態になる。
     
  5. Promise の値が確定する場面
    ・ async 関数の中で、最終的に return 文が実行されるか、エラーがスローされると Promise が「確定(fulfilled または rejected)」する
    ・ 成功した場合(return 文を通る場合): Promise の状態は fulfilled に変わり、返り値が Promise の解決値(value)になる
    ・ 失敗した場合(例: throw 文やエラー発生): Promise の状態は rejected に変わり、エラーが Promise の拒否理由(reason)になる
    例:
    async function afunc() {
      return "結果"; // ここで Promise が解決される
    }
     
    afunc().then(value => {
      console.log(value); // 出力: "結果"
    });
     
  6. Promise の状態変更のタイミング
    Promise の状態(pending, fulfilled, rejected)は、以下の条件で変化します:
    ・ pending(未解決): async 関数を呼び出した直後の状態
    ・ fulfilled(解決): 関数内の処理が完了し、return 文が実行された瞬間
    ・ rejected(拒否): エラーがスローされた瞬間
    例(状態変化の流れ):
    async function afunc() {
      console.log("処理中...");
      await new Promise(resolve => setTimeout(resolve, 1000)); // 1秒待機
      console.log("解決します!");
      return "結果";
    }
      
    const promise = afunc(); // Promise が返される(未解決状態)
    promise.then(value => {
      console.log("Promise解決:", value); // 1秒後に "Promise解決: 結果"
    }).catch(error => {
      console.log("Promise拒否:", error);
    });