You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/02-first-steps/15-function-expressions-arrows/article.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -453,7 +453,7 @@ alert( sum(1, 2) ); // 3
453
453
```smart header="More to come"
454
454
Here we praised arrow functions for brevity. But that's not all! Arrow functions have other interesting features. We'll return to them later in the chapter <info:arrow-functions>.
455
455
456
-
For now, we can already use them for one-line actions and callbacks.
456
+
For now, we can already use arrow functions for one-line actions and callbacks.
Copy file name to clipboardExpand all lines: 1-js/11-async/05-promise-api/article.md
+77-84
Original file line number
Diff line number
Diff line change
@@ -2,65 +2,6 @@
2
2
3
3
There are 5 static methods in the `Promise` class. We'll quickly cover their use cases here.
4
4
5
-
## Promise.resolve
6
-
7
-
The syntax:
8
-
9
-
```js
10
-
let promise =Promise.resolve(value);
11
-
```
12
-
13
-
Returns a resolved promise with the given `value`.
14
-
15
-
Same as:
16
-
17
-
```js
18
-
let promise =newPromise(resolve=>resolve(value));
19
-
```
20
-
21
-
The method is used when we already have a value, but would like to have it "wrapped" into a promise.
22
-
23
-
For instance, the `loadCached` function below fetches the `url` and remembers the result, so that future calls on the same URL return it immediately:
24
-
25
-
```js
26
-
functionloadCached(url) {
27
-
let cache =loadCached.cache|| (loadCached.cache=newMap());
28
-
29
-
if (cache.has(url)) {
30
-
*!*
31
-
returnPromise.resolve(cache.get(url)); // (*)
32
-
*/!*
33
-
}
34
-
35
-
returnfetch(url)
36
-
.then(response=>response.text())
37
-
.then(text=> {
38
-
cache.set(url,text);
39
-
return text;
40
-
});
41
-
}
42
-
```
43
-
44
-
We can use `loadCached(url).then(…)`, because the function is guaranteed to return a promise. That's the purpose `Promise.resolve` serves in the line `(*)`: it makes sure the interface is unified. We can always use `.then` after `loadCached`.
45
-
46
-
## Promise.reject
47
-
48
-
The syntax:
49
-
50
-
```js
51
-
let promise =Promise.reject(error);
52
-
```
53
-
54
-
Create a rejected promise with the `error`.
55
-
56
-
Same as:
57
-
58
-
```js
59
-
let promise =newPromise((resolve, reject) =>reject(error));
60
-
```
61
-
62
-
We cover it here for completeness, rarely used in real code.
63
-
64
5
## Promise.all
65
6
66
7
Let's say we want to run many promises to execute in parallel, and wait till all of them are ready.
@@ -75,9 +16,9 @@ The syntax is:
75
16
let promise =Promise.all([...promises...]);
76
17
```
77
18
78
-
It takes an array of promises (technically can be any iterable, but usually an array) and returns a new promise.
19
+
`Promise.all` takes an array of promises (technically can be any iterable, but usually an array) and returns a new promise.
79
20
80
-
The new promise resolves when all listed promises are settled and has an array of their results.
21
+
The new promise resolves when all listed promises are settled and the array of their results becomes its result.
81
22
82
23
For instance, the `Promise.all` below settles after 3 seconds, and then its result is an array `[1, 2, 3]`:
83
24
@@ -89,7 +30,7 @@ Promise.all([
89
30
]).then(alert); // 1,2,3 when promises are ready: each promise contributes an array member
90
31
```
91
32
92
-
Please note that the relative order is the same. Even though the first promise takes the longest time to resolve, it is still first in the array of results.
33
+
Please note that the order of resulting array members is the same as source promises. Even though the first promise takes the longest time to resolve, it's still first in the array of results.
93
34
94
35
A common trick is to map an array of job data into an array of promises, and then wrap that into `Promise.all`.
95
36
@@ -121,7 +62,7 @@ let requests = names.map(name => fetch(`https://api.github.com/users/${name}`));
121
62
122
63
Promise.all(requests)
123
64
.then(responses=> {
124
-
// all responses are ready, we can show HTTP status codes
65
+
// all responses are resolved successfully
125
66
for(let response of responses) {
126
67
alert(`${response.url}: ${response.status}`); // shows 200 for every url
127
68
}
@@ -159,7 +100,7 @@ For example, if there are multiple `fetch` calls, like in the example above, and
159
100
```
160
101
161
102
````smart header="`Promise.all(iterable)` allows non-promise \"regular\" values in `iterable`"
162
-
Normally, `Promise.all(...)` accepts an iterable (in most cases an array) of promises. But if any of those objects is not a promise, it's wrapped in `Promise.resolve`.
103
+
Normally, `Promise.all(...)` accepts an iterable (in most cases an array) of promises. But if any of those objects is not a promise, it's passed to the resulting array "as is".
163
104
164
105
For instance, here the results are `[1, 2, 3]`:
165
106
@@ -168,8 +109,8 @@ Promise.all([
168
109
newPromise((resolve, reject) => {
169
110
setTimeout(() =>resolve(1), 1000)
170
111
}),
171
-
2,// treated as Promise.resolve(2)
172
-
3// treated as Promise.resolve(3)
112
+
2,
113
+
3
173
114
]).then(alert); // 1, 2, 3
174
115
```
175
116
@@ -180,22 +121,22 @@ So we are able to pass ready values to `Promise.all` where convenient.
180
121
181
122
[recent browser="new"]
182
123
183
-
`Promise.all` rejects as a whole if any promise rejects. That's good in cases, when we need *all* results to go on:
124
+
`Promise.all` rejects as a whole if any promise rejects. That's good for "all or nothing" cases, when we need *all* results to go on:
184
125
185
126
```js
186
127
Promise.all([
187
128
fetch('/template.html'),
188
129
fetch('/style.css'),
189
130
fetch('/data.json')
190
-
]).then(render); // render method needs them all
131
+
]).then(render); // render method needs results of all fetches
191
132
```
192
133
193
-
`Promise.allSettled` waits for all promises to settle: even if one rejects, it waits for the others. The resulting array has:
134
+
`Promise.allSettled` waits for all promises to settle. The resulting array has:
194
135
195
136
- `{status:"fulfilled", value:result}` for successful responses,
196
137
- `{status:"rejected", reason:error}` for errors.
197
138
198
-
For example, we'd like to fetch the information about multiple users. Even if one request fails, we're interested in the others.
139
+
For example, we'd like to fetch the information about multiple users. Even if one request fails, we're still interested in the others.
199
140
200
141
Let's use `Promise.allSettled`:
201
142
@@ -228,7 +169,7 @@ The `results` in the line `(*)` above will be:
228
169
]
229
170
```
230
171
231
-
So, for each promise we get its status and `value/reason`.
172
+
So, for each promise we get its status and `value/error`.
232
173
233
174
### Polyfill
234
175
@@ -237,26 +178,26 @@ If the browser doesn't support `Promise.allSettled`, it's easy to polyfill:
In this code, `promises.map` takes input values, turns into promises (just in case a non-promise was passed) with `p => Promise.resolve(p)`, and then adds `.then` handler to it.
192
+
In this code, `promises.map` takes input values, turns into promises (just in case a non-promise was passed) with `p => Promise.resolve(p)`, and then adds `.then` handler to every one.
252
193
253
194
That handler turns a successful result `v` into `{state:'fulfilled', value:v}`, and an error `r` into `{state:'rejected', reason:r}`. That's exactly the format of `Promise.allSettled`.
254
195
255
196
Then we can use `Promise.allSettled` to get the results or *all* given promises, even if some of them reject.
256
197
257
198
## Promise.race
258
199
259
-
Similar to `Promise.all`, it takes an iterable of promises, but instead of waiting for all of them to finish, it waits for the first result (or error), and goes on with it.
200
+
Similar to `Promise.all`, but waits only for the first settled promise, and gets its result (or error).
260
201
261
202
The syntax is:
262
203
@@ -274,18 +215,70 @@ Promise.race([
274
215
]).then(alert); // 1
275
216
```
276
217
277
-
So, the first result/error becomes the result of the whole `Promise.race`. After the first settled promise "wins the race", all further results/errors are ignored.
218
+
The first promise here was fastest, so it became the result. After the first settled promise "wins the race", all further results/errors are ignored.
219
+
220
+
221
+
## Promise.resolve/reject
222
+
223
+
Methods `Promise.resolve` and `Promise.reject` are rarely needed in modern code, because `async/await` syntax (we'll cover it in [a bit later](info:async-await)) makes them somewhat obsolete.
224
+
225
+
We cover them here for completeness, and for those who can't use `async/await` for some reason.
226
+
227
+
- `Promise.resolve(value)` creates a resolved promise with the result `value`.
228
+
229
+
Same as:
230
+
231
+
```js
232
+
let promise = new Promise(resolve => resolve(value));
233
+
```
234
+
235
+
The method is used for compatibility, when a function is expected to return a promise.
236
+
237
+
For example, `loadCached` function below fetches URL and remembers (caches) its content. For future calls with the same URL it immediately gets the previous content from cache, but uses `Promise.resolve` to make a promise of it, so that the returned value is always a promise:
238
+
239
+
```js
240
+
let cache = new Map();
241
+
242
+
function loadCached(url) {
243
+
if (cache.has(url)) {
244
+
*!*
245
+
return Promise.resolve(cache.get(url)); // (*)
246
+
*/!*
247
+
}
248
+
249
+
return fetch(url)
250
+
.then(response => response.text())
251
+
.then(text => {
252
+
cache.set(url,text);
253
+
return text;
254
+
});
255
+
}
256
+
```
257
+
258
+
We can write `loadCached(url).then(…)`, because the function is guaranteed to return a promise. We can always use `.then` after `loadCached`. That's the purpose of `Promise.resolve` in the line `(*)`.
259
+
260
+
### Promise.reject
261
+
262
+
- `Promise.reject(error)` creates a rejected promise with `error`.
263
+
264
+
Same as:
265
+
266
+
```js
267
+
let promise = new Promise((resolve, reject) => reject(error));
268
+
```
269
+
270
+
In practice, this method is almost never used.
278
271
279
272
## Summary
280
273
281
274
There are 5 static methods of `Promise` class:
282
275
283
-
1. `Promise.resolve(value)` -- makes a resolved promise with the given value.
284
-
2. `Promise.reject(error)` -- makes a rejected promise with the given error.
285
-
3. `Promise.all(promises)` -- waits for all promises to resolve and returns an array of their results. If any of the given promises rejects, then it becomes the error of `Promise.all`, and all other results are ignored.
286
-
4. `Promise.allSettled(promises)` (a new method) -- waits for all promises to resolve or reject and returns an array of their results as object with:
287
-
- `state`: `'fulfilled'` or `'rejected'`
276
+
1. `Promise.all(promises)` -- waits for all promises to resolve and returns an array of their results. If any of the given promises rejects, then it becomes the error of `Promise.all`, and all other results are ignored.
277
+
2. `Promise.allSettled(promises)` (recently added method) -- waits for all promises to settle and returns their results as array of objects with:
278
+
- `state`: `"fulfilled"` or `"rejected"`
288
279
- `value` (if fulfilled) or `reason` (if rejected).
289
-
5. `Promise.race(promises)` -- waits for the first promise to settle, and its result/error becomes the outcome.
280
+
3. `Promise.race(promises)` -- waits for the first promise to settle, and its result/error becomes the outcome.
281
+
4. `Promise.resolve(value)` -- makes a resolved promise with the given value.
282
+
5. `Promise.reject(error)` -- makes a rejected promise with the given error.
290
283
291
284
Of these five, `Promise.all` is probably the most common in practice.
0 commit comments