1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
---
title: Promise.race()
slug: Web/JavaScript/Reference/Global_Objects/Promise/race
tags:
- ECMAScript 2015
- JavaScript
- メソッド
- Promise
- リファレンス
browser-compat: javascript.builtins.Promise.race
translation_of: Web/JavaScript/Reference/Global_Objects/Promise/race
---
{{JSRef}}
**`Promise.race()`** メソッドは、反復可能オブジェクトの中のプロミスのうちの 1 つが履行されるか拒否されると、そのプロミスの値または理由で履行または拒否されるプロミスを返します。
{{EmbedInteractiveExample("pages/js/promise-race.html", "taller")}}
## 構文
```js
Promise.race(iterable);
```
### 引数
- `iterable`
- : 配列 ({{jsxref("Array")}}) などの反復可能なオブジェクト。[反復可能](/ja/docs/Web/JavaScript/Reference/Iteration_protocols#反復可能_iterable_プロトコル)を確認してください。</dd>
### 返値
**待ち状態の** {{jsxref("Promise")}} で、反復可能オブジェクトの中で最初に履行または解決されたプロミスの値を**非同期に**産出します。
## 解説
`race` 関数は、引数として渡された反復可能オブジェクトの中にある複数のプロミスの中で決定した最初のプロミスと同じ方法で決定される(同じ値を取る)プロミスを返します。
渡された反復可能オブジェクトが空の場合、返されるプロミスは永遠に待機状態のままです。
反復可能オブジェクトに 1 つ以上のプロミス以外の値やすでに決定済みのプロミスが含まれていた場合、 `Promise.race` は反復可能オブジェクトの中で見つけたこれらの値の内の最初の一つで解決します。
## 例
### Promise.race の非同期性
以下の例は、 `Promise.race` の非同期性を示しています。
```js
// Promise.rac eをできるだけ早く起動させるために、解決済みのプロミスの配列を
// 引数として渡しています。
var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)];
var p = Promise.race(resolvedPromisesArray);
// 直ちに p の値を出力
console.log(p);
// setTimeout を使用すると、スタックが空になった後でコードが実行される
setTimeout(function(){
console.log('スタックが空です');
console.log(p);
});
// logs, in order:
// Promise { <state>: "pending" }
// スタックが空です
// Promise { <state>: "fulfilled", <value>: 33 }
```
空の反復可能オブジェクトを渡すと、無限に解決しないプロミスが返されます。
```js
var foreverPendingPromise = Promise.race([]);
console.log(foreverPendingPromise);
setTimeout(function(){
console.log('スタックが空です');
console.log(foreverPendingPromise);
});
// ログ(順番に):
// Promise { <state>: "pending" }
// スタックが空です
// Promise { <state>: "pending" }
```
反復可能オブジェクトの中に 1 つ以上のプロミス以外の値や、すでに解決したプロミスが含まれていると、 `Promise.race` は配列の中で見つかった最初のこれらの値で解決します。
```js
var foreverPendingPromise = Promise.race([]);
var alreadyFulfilledProm = Promise.resolve(100);
var arr = [foreverPendingPromise, alreadyFulfilledProm, "non-Promise value"];
var arr2 = [foreverPendingPromise, "non-Promise value", Promise.resolve(100)];
var p = Promise.race(arr);
var p2 = Promise.race(arr2);
console.log(p);
console.log(p2);
setTimeout(function(){
console.log('スタックが空です');
console.log(p);
console.log(p2);
});
// ログ(順番に)
// Promise { <state>: "pending" }
// Promise { <state>: "pending" }
// スタックが空です
// Promise { <state>: "fulfilled", <value>: 100 }
// Promise { <state>: "fulfilled", <value>: "non-Promise value" }
```
### Promise.race の使用 – setTimeout を使用した例
```js
var p1 = new Promise(function(resolve, reject) {
setTimeout(() => resolve('one'), 500);
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(() => resolve('two'), 100);
});
Promise.race([p1, p2])
.then(function(value) {
console.log(value); // "two"
// 両方が履行されるが、 p2 の方が早い
});
var p3 = new Promise(function(resolve, reject) {
setTimeout(() => resolve('three'), 100);
});
var p4 = new Promise(function(resolve, reject) {
setTimeout(() => reject(new Error('four')), 500);
});
Promise.race([p3, p4])
.then(function(value) {
console.log(value); // "three"
// p3 の方が早いので、履行される
}, function(error) {
// Not called
});
var p5 = new Promise(function(resolve, reject) {
setTimeout(() => resolve('five'), 500);
});
var p6 = new Promise(function(resolve, reject) {
setTimeout(() => reject(new Error('six')), 100);
});
Promise.race([p5, p6])
.then(function(value) {
// 呼び出されない
}, function(error) {
console.log(error.message); // "six"
// p6 の方が早いので、拒否される
});
```
### Promise.any との比較
`Promise.race` は最初に決定された {{jsxref("Promise")}} を取ります。
```js
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 100, 'two');
});
Promise.race([promise1, promise2]).then((value) => {
console.log('succeeded with value:', value);
}).catch((reason) => {
// Only promise1 is fulfilled, but promise2 is faster
console.log('failed with reason:', reason);
});
// 期待される出力: "failed with reason: two"
```
{{jsxref("Promise.any")}} は最初に履行された {{jsxref("Promise")}} を取ります。
```js
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 100, 'two');
});
Promise.any([promise1, promise2]).then((value) => {
// promise1 のみが履行されるが、 promise2 の方が早く決定する
console.log('succeeded with value:', value);
}).catch((reason) => {
console.log('failed with reason:', reason);
});
// 期待される出力: "succeeded with value: one"
```
## 仕様書
{{Specifications}}
## ブラウザーの互換性
{{Compat}}
## 関連情報
- {{jsxref("Promise")}}
- {{jsxref("Promise.all()")}}
|