記事検索

検索ワードを入力してください。
Sky Tech Blog
【JavaScript】Promiseチェーンと​try-catchを​用いた​エラーハンドリング

【JavaScript】Promiseチェーンと​try-catchを​用いた​エラーハンドリング

JavaScriptにおける非同期処理のエラーハンドリングについて、Promiseとtry-catchを用いた具体例を交えながら説明しています。Promiseの状態やエラーハンドリングの方法、処理の順番や出力結果について紹介しています。

JavaScriptでは、非同期処理を扱う際にPromiseとtry-catchを使ってエラー処理が行われます。
APIからデータを取得する場合やダイアログ操作など、一般的な開発シーンでも頻繁に使用されます。

本記事では具体例を交えながら、エラーハンドリングについて解説しているので、処理の順番や出力結果を予想しながらご覧いただければ幸いです。

Promiseに​ついて

Promiseは以下の3つの状態を持ちます。

  • 待機(Pending):初期状態または処理中の状態。
  • 成功(Fulfilled):処理が成功して完了した状態。
  • 拒否(Rejected):処理が失敗した状態。

以下の処理では、count.valueが偶数の場合は成功状態、それ以外の場合は拒否状態となります。

const getPromise = () => {
  return new Promise((resolve, reject) => {
    if (count.value % 2 === 0) {
      resolve("test: promise resolve");
    } else {
      reject("test: promise reject");
    }
  });
};

以下の処理では、Promiseチェーンを使って結果を処理しています。

getPromise()
  .then((message) => {
    console.log(message); // "test: promise resolve"が出力される
  })
  .catch((message) => {
    console.log(message); // "test: promise reject"が出力される
  });
  • resolve関数が呼ばれると、Promiseは成功(Fulfilled)状態になり、thenメソッドに渡されたコールバック関数が実行されます。
    この場合、"test: promise resolve"がコンソールログに出力されます。

  • reject関数が呼ばれると、Promiseは拒否(Rejected)状態になり、catchメソッドに渡されたコールバック関数が実行されます。
    この場合、"test: promise reject"がコンソールログに出力されます。

try-catchに​ついて

tryブロック内で発生したエラーをcatchブロックで捕まえることができます。

以下の処理では"try-error"がコンソールログに出力されます。

try {
    // 明示的にエラーを投げています
    throw "try-error";
} catch (e) {
    console.log(e); // "try-error"が出力される
}

Promiseチェーンと​try-catchを​用いた​エラーハンドリング

2つのパターンを用いて解説します。

パターン①

以下の処理でgetPromiseがresolveまたはrejectを呼び出した場合のコンソールログはどうなるでしょうか。
※awaitがついている関数については、処理が完了するまで待機状態になります。

async function syncProcess1() {
  try {
    await getPromise()
      .then(() => {
        console.log("promise-resolve");
      })
      .catch(() => {
        console.log("promise-reject");
      });
    console.log("passed-promise");
  } catch (e) {
    console.log("try-catch");
  } finally {
    console.log("try-finally");
  }
}

結果

resolveの​場合
  • promise-resolve
  • passed-promise
  • try-finally
rejectの​場合
  • promise-reject
  • passed-promise
  • try-finally

解説

まず、getPromise関数はawaitが付いているため待機状態となり、resolveまたはrejectが呼ばれて処理完了するまで後続処理は実行されません。
getPromiseでresolveが呼ばれると、.thenの"promise-resolve"が出力され、rejectで拒否状態になると.catchの"promise-reject"が出力されます。
getPromiseがrejectで拒否されても、getPromiseの.catchで処理を拾うため、tryのcatchには捕まらずに後続の処理を実行します。

パターン②

次に、パターン①のコードのgetPromise関数のawaitを除いた場合の処理を考えてみましょう。
以下の処理で、getPromiseがresolveまたはrejectを呼んだ場合のコンソールログはどうなるでしょうか。

function syncProcess2() {
  try {
    getPromise()
      .then(() => {
        console.log("promise-resolve");
      })
      .catch(() => {
        console.log("promise-reject");
      });
    console.log("passed-promise");
  } catch (e) {
    console.log("try-catch");
  } finally {
    console.log("try-finally");
  }
}

結果

resolveの​場合
  • passed-promise
  • try-finally
  • promise-resolve
rejectの​場合
  • passed-promise
  • try-finally
  • promise-reject

解説

awaitが付いていないgetPromiseは、非同期処理となるため、後続の同期処理が優先して実行されます。
たとえ後続の同期処理が時間のかかる処理であっても、Promiseのログは一番最後に出力されます。
(JavaScriptのイベントループでは、コールスタックで同期処理、タスクキューで非同期処理を管理しており、コールスタックの処理がすべてなくなった後、タスクキューの処理が呼ばれる仕組みのため)


\シェアをお願いします!/
  • X
  • Facebook
  • LINE
キャリア採用募集中!

入社後にスキルアップを目指す若手の方も、ご自身の経験を幅広いフィールドで生かしたいベテランの方も、お一人おひとりの経験に応じたキャリア採用を行っています。

Sky株式会社のソフトウェア開発や製品、採用に関するお問い合わせについては、下記のリンクをご確認ください。
お問い合わせ
ホーム