Node.js Promise

Promise は、Node.js で非同期操作を処理する核心的な概念の一つです。

Promise は、非同期コードを管理するより洗練された方法を提供し、従来のコールバック地獄(Callback Hell)の問題を回避します。

この記事では、Promise の概念、使用方法、一般的なパターンについて詳しく説明します。


Promise とは?

Promise は、非同期操作の最終的な完了または失敗を表すオブジェクトです。3つの状態があります:

  1. 待機中:初期状態であり、成功でも失敗でもありません
  2. Fulfilled(成功):操作が正常に完了しました
  3. Rejected(失敗):操作が失敗しました

Promise の状態は一度変更されると(pending から fulfilled または rejected へ)、その後は変更されません。


Promise の作成

Node.js では、Promiseコンストラクタを使用して新しい Promise オブジェクトを作成できます:

例

const myPromise = new Promise((resolve, reject) => {
  // 异步操作
  const success = true; // これは非同期操作の結果であると仮定します
 
  if (success) {
    resolve('操作成功!'); // 状態が fulfilled に変わる
  } else {
    reject('操作失败!'); // 状態が rejected になる
  }
});

Promise の使用

Promise には.then()と.catch()メソッドが用意されており、成功と失敗のケースを処理します:

例

myPromise
  .then((result) => {
    console.log(result); // 输出:"操作成功!"
  })
  .catch((error) => {
    console.error(error); // 输出:"操作失败!"
  });

Promise のチェーン呼び出し

Promise の強力な点は、複数の非同期操作をチェーン呼び出しできることです:

例

function asyncOperation1() {
  return new Promise((resolve) => {
    setTimeout(() => resolve('第一步完成'), 1000);
  });
}

function asyncOperation2(data) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(`${data},第二步完成`), 1000);
  });
}

asyncOperation1()
  .then((result) => asyncOperation2(result))
  .then((finalResult) => {
    console.log(finalResult); // 输出:"第一步完成, 第二步完成"
  })
  .catch((error) => {
    console.error('链式中出错:', error);
  });

Promise の静的メソッド

Promise には便利な静的メソッドがいくつか用意されています:

Promise.all()

すべての Promise が完了するのを待つか、いずれかの Promise が失敗するのを待ちます:

例

const promise1 = Promise.resolve('第一个');
const promise2 = Promise.resolve('第二个');

Promise.all([promise1, promise2])
  .then((results) => {
    console.log(results); // 输出:['第一个', '第二个']
  });

Promise.race()

最初に完了または失敗した Promise を返します:

例

const promise1 = new Promise((resolve) => setTimeout(resolve, 500, '第一个'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, '第二个'));

Promise.race([promise1, promise2])
  .then((result) => {
    console.log(result); // 输出:"第二个"
  });

エラー処理

Promise のエラー処理は、.catch() 或 .then()の2番目の引数を使用して実装できます:

例

someAsyncFunction()
  .then(
    (result) => { /* 处理成功 */ },
    (error) => { /* 处理失败 */ }
  );

// 或者
someAsyncFunction()
  .then((result) => { /* 处理成功 */ })
  .catch((error) => { /* 处理所有错误 */ });

async/await 構文

ES2017 で async/await 構文が導入され、Promise の使用がより直感的になりました:

例

async function runOperations() {
  try {
    const result1 = await asyncOperation1();
    const result2 = await asyncOperation2(result1);
    console.log(result2);
  } catch (error) {
    console.error(error);
  }
}

runOperations();

ベストプラクティス

  1. 常にエラーを処理する:無視しない.catch()または try-catch
  2. ネストを避ける:チェーン呼び出しまたは async/await を使用してコードをフラットに保つ
  3. Promise に名前を付ける:Promise 変数に意味のある名前を付ける
  4. Promise を返す:チェーン呼び出しのために、関数内で Promise を返す
その他の拡張