Promise.all() で複数のPromiseを待つ
JavaScriptにおけるPromiseの処理: 全てのPromiseが完了するまで待つ
JavaScriptのPromiseは非同期処理の管理に用いられます。複数のPromiseを並列に実行し、全てが完了するまで待機する状況がしばしば発生します。このとき、一部のPromiseが失敗(rejected)しても、残りのPromiseが完了するまで待つことができます。
Promise.all()の使用
Promise.all()
メソッドは、複数のPromiseを受け取り、全てが完了または失敗するまで待機します。このメソッドは、全てのPromiseが完了した場合にのみ成功(resolved)し、いずれかのPromiseが失敗した場合には失敗(rejected)します。
コード例
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 1 fulfilled');
}, 1000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('Promise 2 rejected');
}, 500);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Pro mise 3 fulfilled');
}, 2000);
});
Promise.all([promise1, promise2, promise3])
.then((results) => {
console.log('All promises fulfilled:', results);
})
.catch((error) => {
console.error('At least one promise rejected :', error);
});
解説
- 3つのPromiseを作成します。
Promise.all()
を使用して、これら3つのPromiseを並列に実行します。promise2
は失敗しますが、他のPromiseが完了するまで待機します。- 全てのPromiseが完了または失敗した後、
then
またはcatch
ブロックが実行されます。
ポイント
- 失敗したPromiseの理由を特定するには、
catch
ブロックでエラー情報を取得します。 Promise.all()
は、全てのPromiseが完了した場合のみ成功します。
ES6 Promiseの利用
このコードはES6のPromiseを使用しています。ES5でPromiseを使用する場合、Polyfill(例えば、es6-promise)が必要となります。
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 1 fulfilled');
}, 1000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('Promise 2 rejected');
}, 500);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Pro mise 3 fulfilled');
}, 2000);
});
Promise.all([promise1, promise2, promise3])
.then((results) => {
console.log('All promises fulfilled:', results);
})
.catch((error) => {
console.error('At least one promise rejected :', error);
});
JavaScriptにおけるPromiseの処理: 全てのPromiseが完了するまで待つ(Promise.all()以外の方法)
Promise.all()
以外にも、複数のPromiseを待つ方法があります。
forループとPromise.resolve()
const promises = [promise1, promise2, promise3];
let resolvedPromises = 0;
let rejectedPromises = 0;
for (const promise of promises) {
promise
.then(() => {
resolvedPromises++;
if (resolvedPromises + rejectedPromises === promises.length) {
// 全てのPromiseが完了
console.log('All promises completed');
}
})
.catch(() => {
rejectedPromises++;
if (resolvedPromises + rejectedPromises === promises.length) {
// 全てのPromiseが完了
console.log('All promises completed');
}
});
}
Promise.race()とPromise.allSettled()
const promises = [promise1, promise2, promise3];
Promise.race(promises)
.then(() => {
// 最初に完了したPromiseの結果
Promise.allSettled(promises)
.then((results) => {
// 全てのPromiseの結果
console.log('All promises settled:', results);
});
})
.catch((error) => {
// 最初に失敗したPromiseのエラー
console.error('At least one promise rejected:', error);
});
async/await
async function waitForAllPromises() {
const promises = [promise1, promise2, promise3];
try {
const results = await Promise.all(promises);
console.log('All promises fulfilled:', results);
} catch (error) {
console.error('At least one promise rejected:', error);
}
}
waitForAllPromises();
- async/await: 非同期処理を同期的に記述できるため、コードが読みやすくなります。
- Promise.race()とPromise.allSettled(): 最初に完了したPromiseの結果を取得し、その後、全てのPromiseの結果を取得します。
- forループとPromise.resolve(): 逐次的にPromiseを処理し、全てのPromiseが完了したかどうかをカウントします。
選択基準
- async/await: 非同期処理を同期的に記述したい場合に適している。
- Promise.race()とPromise.allSettled(): 最初に完了したPromiseの結果が必要な場合に適している。
- forループとPromise.resolve(): 柔軟性が高く、カスタム処理が可能。
- Promise.all(): シンプルで使いやすい。
javascript promise es6-promise