Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

JavaScript辞典

  1. トップページ
  2. JavaScript辞典
  3. Promise.all() / allSettled() / race() / any()

Promise.all() / allSettled() / race() / any()対応: ES6(ECMAScript 2015)

複数のPromiseをまとめて管理するための静的メソッドです。すべての完了を待つ、最初の完了を待つなど、用途に応じた4つのメソッドが用意されています。

構文
// すべてのPromiseが成功するのを待ちます。1つでも失敗すると即座に失敗します。
Promise.all([promise1, promise2, ...]);

// すべてのPromiseが完了するのを待ちます。成功・失敗を問いません。
Promise.allSettled([promise1, promise2, ...]);

// 最初に完了したPromiseの結果を返します。成功・失敗を問いません。
Promise.race([promise1, promise2, ...]);

// 最初に成功したPromiseの結果を返します。すべて失敗した場合のみ失敗します。
Promise.any([promise1, promise2, ...]);
メソッド一覧
メソッド概要
Promise.all(配列)すべてのPromiseが成功した場合に、結果の配列を返します。1つでも失敗すると、最初に失敗したエラーで即座に失敗します。
Promise.allSettled(配列)すべてのPromiseが完了するのを待ち、各Promiseの結果を配列で返します。成功・失敗の情報がそれぞれ含まれます。
Promise.race(配列)最初に完了したPromiseの結果を返します。それが成功でも失敗でも、最初の1つで結果が確定します。
Promise.any(配列)最初に成功したPromiseの結果を返します。すべてが失敗した場合のみ『AggregateError』で失敗します。
サンプルコード
// テスト用のPromise生成関数
function fetchData(name, ms, shouldFail) {
	return new Promise(function(resolve, reject) {
		setTimeout(function() {
			if (shouldFail) {
				reject(name + "の取得に失敗");
			} else {
				resolve(name + "のデータ");
			}
		}, ms);
	});
}

// Promise.all() はすべての成功を待ちます。
Promise.all([
	fetchData("ユーザー", 1000, false),
	fetchData("記事", 2000, false),
	fetchData("コメント", 1500, false)
]).then(function(results) {
	console.log(results); // すべて成功した場合、結果の配列が出力されます。
}).catch(function(error) {
	console.log(error); // 1つでも失敗すると、ここが実行されます。
});

// Promise.allSettled() は成功・失敗を問わず全結果を取得します。
Promise.allSettled([
	fetchData("API-A", 1000, false),
	fetchData("API-B", 500, true),
	fetchData("API-C", 1500, false)
]).then(function(results) {
	results.forEach(function(r) {
		if (r.status === "fulfilled") {
			console.log("成功: " + r.value);
		} else {
			console.log("失敗: " + r.reason);
		}
	});
});

// Promise.race() は最初に完了した結果を返します。
Promise.race([
	fetchData("高速サーバー", 500, false),
	fetchData("低速サーバー", 3000, false)
]).then(function(result) {
	console.log(result); // 最初に完了した結果が出力されます。
});

// Promise.any() は最初に成功した結果を返します。
Promise.any([
	fetchData("サーバー1", 1000, true),
	fetchData("サーバー2", 2000, false),
	fetchData("サーバー3", 1500, false)
]).then(function(result) {
	console.log(result); // 最初に成功した結果が出力されます。
});
実行結果
// Promise.all() — すべて成功した場合
["ユーザーのデータ", "記事のデータ", "コメントのデータ"]

// Promise.allSettled() — 成功と失敗が混在する場合
"成功: API-Aのデータ"
"失敗: API-Bの取得に失敗"
"成功: API-Cのデータ"

// Promise.race() — 最初に完了した結果
"高速サーバーのデータ"

// Promise.any() — 最初に成功した結果
"サーバー2のデータ"
概要

これら4つのメソッドは、複数の非同期処理を効率的に管理するためのものです。最もよく使われるのは『Promise.all()』で、複数のAPIから同時にデータを取得し、すべての取得が完了してからまとめて処理するパターンで活躍します。並列に実行されるため、順番に実行するよりも処理時間を短縮できます。

『Promise.all()』は1つでも失敗すると全体が失敗するため、一部の失敗を許容したい場合は『Promise.allSettled()』を使用します。各結果には『status』プロパティが含まれ、『"fulfilled"』なら成功で『value』に結果が、『"rejected"』なら失敗で『reason』にエラー情報が格納されています。

『Promise.race()』はタイムアウト処理の実装によく使われます。データ取得のPromiseとタイマーのPromiseを競わせて、一定時間内に応答がなければタイムアウトとする、というパターンです。『Promise.any()』は複数のサーバーに同時にリクエストを送り、最初に成功した結果を採用する冗長化の実装に向いています。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。