Node.js Promise
Promise は、Node.js で非同期操作を処理する核心的な概念の一つです。
Promise は、非同期コードを管理するより洗練された方法を提供し、従来のコールバック地獄(Callback Hell)の問題を回避します。
この記事では、Promise の概念、使用方法、一般的なパターンについて詳しく説明します。
Promise とは?
Promise は、非同期操作の最終的な完了または失敗を表すオブジェクトです。3つの状態があります:
- 待機中:初期状態であり、成功でも失敗でもありません
- Fulfilled(成功):操作が正常に完了しました
- 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 になる
}
});
// 异步操作
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); // 输出:"操作失败!"
});
.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);
});
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); // 输出:['第一个', '第二个']
});
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); // 输出:"第二个"
});
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) => { /* 处理所有错误 */ });
.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();
try {
const result1 = await asyncOperation1();
const result2 = await asyncOperation2(result1);
console.log(result2);
} catch (error) {
console.error(error);
}
}
runOperations();
ベストプラクティス
- 常にエラーを処理する:無視しない
.catch()または try-catch - ネストを避ける:チェーン呼び出しまたは async/await を使用してコードをフラットに保つ
- Promise に名前を付ける:Promise 変数に意味のある名前を付ける
- Promise を返す:チェーン呼び出しのために、関数内で Promise を返す