Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 24e8567

Browse files
committed
extended promises fundamental
2 parents 7e92772 + a0a38a6 commit 24e8567

File tree

1 file changed

+52
-17
lines changed

1 file changed

+52
-17
lines changed

fundamentals/promises.md

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,29 @@ function getJSON(url) {
88
const xhr = new XMLHttpRequest();
99
xhr.open('GET', url);
1010
xhr.responseType = 'json';
11-
xhr.onload = () => resolve(xhr.response);
12-
xhr.onerror = () => reject(xhr.statusText);
1311
xhr.send();
12+
xhr.onload = () => {
13+
if (xhr.status < 400) {
14+
resolve(xhr.response);
15+
} else {
16+
reject(new Error(xhr.statusText));
17+
}
18+
};
19+
xhr.onerror = () => reject(new Error(xhr.statusText));
1420
});
1521
}
1622

1723
// alternative:
1824
const fetchJSON = url => fetch(url).then(res => res.json());
1925

20-
...
26+
// ...
2127

22-
getJSON(apiEndpoint)
23-
.then(res => renderData(res))
28+
getJSON(url)
29+
.then(data => renderData(data))
2430
.catch(err => renderError(err));
2531
```
2632

27-
Listing 1. Asynchronous `XMLHttpRequest` (and `fetch` alternative) using a promise
33+
Listing 1. Asynchronous `XMLHttpRequest` (and `fetch` alternative) using a promise.
2834

2935
The `getJSON()` function in Listing 1 returns a `promise` that resolves to some value converted from JSON data received from some remote API end point. The `fetchJSON()` function does the same, using a more modern browser Web API.
3036

@@ -36,7 +42,7 @@ Why is a JavaScript ES6 `promise` called a 'promise'? Here is a snippet from the
3642
noun<br>
3743
1 a declaration or assurance that one will do something or that a particular thing will happen
3844

39-
This pretty well sums up what a promise means in JavaScript: something that will be delivered in the future (if and when the promise is *fulfilled*).
45+
This pretty well sums up what a promise means in JavaScript: something that will be delivered in the future (if and when the promise is *fulfilled*).
4046

4147
Traditionally, *callbacks* are used as a way to receive the data that is delivered asynchronously (meaning that the data is not likely to be available at the time it is requested but can be expected 'to happen' some time later). Using callbacks can quickly become unwieldy when dealing with many asynchronous events (e.g., ajax calls), especially when they depend on each other (google for *callback hell*).
4248

@@ -53,7 +59,7 @@ We can state a number of simple facts about ES6 promises:
5359
- **fulfilled**: the asynchronous result has been delivered and ready (`resolve` was called)
5460
- **rejected**: an error was encountered: the promise could not be fulfilled (`reject` was called)
5561
- A promise that is no longer pending because it was either fulfilled to rejected is said to be _settled_.
56-
- A promise that is _settled_ has reached its final state. Its state and value can no longer be changed.
62+
- A promise that is _settled_ has reached its final state. Its state and value can no longer be changed. It has become _immutable_.
5763

5864
## The .then() method
5965

@@ -63,7 +69,7 @@ A promise exposes a `.then()` method through which you can obtain its fulfilled
6369
somePromise.then(onFulfilled, onRejected)
6470
```
6571

66-
The `.then()` method takes two **optional** callbacks, the first one dealing with the 'happy' scenario (the promise is fulfilled) and the second one dealing with the error case (the promise is rejected). If you are only interested in the success case you can leave out the second callback:
72+
The `.then()` method takes as its parameters two **optional** functions, the first one dealing with the 'happy' scenario (the promise is fulfilled) and the second one dealing with the error case (the promise is rejected). If you are only interested in the success case you can leave out the second parameter:
6773

6874
```js
6975
somePromise.then(onFulfilled)
@@ -81,25 +87,54 @@ or you can use a second method exposed by a promise, which is just a short-hand
8187
somePromise.catch(onRejected)
8288
```
8389

84-
> Note: the callback functions passed as arguments to the `.then()` method are always called asynchronously, even if the promise was already settled.
90+
> Note that `onFulfilled` and `onRejected` execute asynchronously, after the [event loop](./event_loop.md) turn in which then is called, and with a fresh stack.
8591
86-
It is also important to understand that the `.then()` method returns a new promise that resolves to the return value of the `onFulfilled` callback (if specified) in case of the 'happy' scenario or the return value of the `onRejected` callback (if specified) in case of an error. If the return value of these functions is a plain JavaScript value, the new promise is immediately fulfilled with that value. If the return value is yet another promise then that promise itself is the fulfillment value. If the function does not return a value, the new promise is immediately fulfilled with the value `undefined`.
92+
It is also important to understand that the `.then()` method returns a new promise that resolves to the return value of `onFulfilled` (if specified) in case of the 'happy' scenario or the return value of `onRejected` (if specified) in case of an error. If the return value of these functions is a plain JavaScript value, the new promise is immediately fulfilled with that value. If the return value is yet another promise then the settlement value is of that inner promise, when settled. If the function does not return a value, the new promise is immediately fulfilled with the value `undefined`.
8793

8894
Because `.then()` (and `.catch`) return new promises, you can chain them together such that your code can be read as: do *this*, then do *that* and then *that*, etc.:
8995

9096
```js
91-
fetchJSON(apiUrl)
97+
getJSON(url)
9298
.then(data => {
93-
renderData(data);
94-
return fetchJSON(otherUrl);
99+
const innerPromise = getJSON(otherUrl)
100+
.then(otherData => {
101+
renderData(data);
102+
renderOtherData(otherData);
103+
});
104+
return innerPromise;
95105
})
96-
.then(otherData => renderOther(otherData))
97-
.catch(error => handleError(error));
106+
.catch(err => {
107+
renderError(error)
108+
});
98109
```
99110

100111
Listing 2. Chaining of `then` and `catch`
101112

102-
More information:
113+
Let's examine Listing 2 in a bit more detail. There two calls to `getJSON()`. Errors are to be handled in one place, by means of the `.catch()` method that terminates the promise "chain".
114+
115+
If you embed another promise inside the function that you pass to the `.then()` method you should return that promise as the function's return value. If you don't return the promise, you will break the promise chain and the single `.catch()` at the end of the chain will not catch all errors.
116+
117+
Note the expression assigned to the `innerPromise` variable. The `getJSON()` function returns a promise, but the `.then()` method chained to `getJSON()` also returns a promise (resolved to the value `undefined` because no value is returned). Therefore `innerPromise` is indeed a promise. In this case we are not interested in the value it resolves to (which is `undefined` as we saw), only in the fact that the promise is resolved (i.e. the async operation we were waiting for has been completed).
118+
119+
In case a promise in the chain is rejected due to some error, the promise chain will be traversed until an `onRejected` handler (e.g., in a terminating `.catch()` method) is found. All intermediate `onFulfilled` handlers (e.g. `.then()`) will be skipped*.
120+
121+
Handling errors at the end of a promise chain is a major advantage over the repetition of error handling code in the case of callbacks.
122+
123+
\* Note: `.catch(onRejected)` is a shorthand for `.then(null, onRejected)`.
124+
125+
## Further readings
126+
127+
Our previous students also enjoyed learning about promises at:
128+
129+
In text:
130+
131+
- http://javascript.info/promise-basics
132+
- https://blog.cloudboost.io/explaining-basic-javascript-promises-in-jip-en-janneketaal-c98763c0abd6
133+
- https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261
134+
135+
Video: The net Ninja: https://www.youtube.com/watch?v=yswb4SkDoj0
136+
137+
MDN:
103138

104139
- [MDN - Promise definition](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
105140
- [MDN - Using Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)

0 commit comments

Comments
 (0)