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

Skip to content

Commit 7e92772

Browse files
committed
extended promises fundamental
1 parent 9a15e40 commit 7e92772

File tree

1 file changed

+36
-34
lines changed

1 file changed

+36
-34
lines changed

fundamentals/promises.md

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,30 @@
33
Listing 1 shows an example based on an asynchronous XMLHttpRequest that we will use throughout this discussion.
44

55
```js
6-
function getJSON(url, method) {
6+
function getJSON(url) {
77
return new Promise((resolve, reject) => {
88
const xhr = new XMLHttpRequest();
9-
xhr.addEventListener("load", () => resolve(xhr.responseText));
10-
xhr.addEventListener("error", () => reject(xhr.statusText));
11-
xhr.open(method, url);
9+
xhr.open('GET', url);
10+
xhr.responseType = 'json';
11+
xhr.onload = () => resolve(xhr.response);
12+
xhr.onerror = () => reject(xhr.statusText);
1213
xhr.send();
13-
}).then(res => JSON.parse(res))
14+
});
1415
}
1516

16-
const fetchJSON = url => fetch(url).then(res => res.json())
17+
// alternative:
18+
const fetchJSON = url => fetch(url).then(res => res.json());
1719

1820
...
1921

20-
getJSON(HYFReposApiEndpoint)
21-
.then(res => getHtmlRepoList(res))
22-
.then(html => renderList($repoList, html))
23-
.catch(() => renderList($repoList, '<li>Error</li>'))
22+
getJSON(apiEndpoint)
23+
.then(res => renderData(res))
24+
.catch(err => renderError(err));
2425
```
2526

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

28-
The `getJSON()` function call 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.
29+
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.
2930

3031
## What is a promise?
3132

@@ -35,30 +36,34 @@ Why is a JavaScript ES6 `promise` called a 'promise'? Here is a snippet from the
3536
noun<br>
3637
1 a declaration or assurance that one will do something or that a particular thing will happen
3738

38-
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*). 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*).
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*).
40+
41+
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*).
3942

4043
JavaScript ES6 introduces promises as a better alternative for callbacks when dealing with asynchronous events.
4144

4245
We can state a number of simple facts about ES6 promises:
4346

44-
- A promise is a JavaScript object (`typeof somePromise === 'object'`).
45-
- Because a promise is an ordinary JavaScript object you can pass it around as an argument to a function, return it from a function, assign it to a variable, etc.
46-
- You can create one yourself by calling the ES6 `Promise` constructor function with `new` (like we're doing in Listing 1 above), then call `resolve` when results are ready or `reject` on detecting an error.
47+
- A promise is a JavaScript object (`typeof somePromise === 'object'`) that serves as a placeholder for a (future) value.
48+
- Because a promise is an ordinary JavaScript object you can pass it around as an argument to a function, return it from a function, assign it to a variable, push it to an array, etc.
49+
- You can create one yourself by calling the ES6 `Promise` constructor function with `new` (as we're doing in Listing 1 above), then call `resolve` when results are ready or `reject` on detecting an error.
4750
- Sometimes you can get a ready-made promise by calling an appropriate API or library function, like the `fetch` Web API function in Listing 1.
48-
- Internally, a promise can be in three states:
51+
- Internally, a promise can be in one of three states:
4952
- **pending**: the asynchronous result is still awaiting delivery
5053
- **fulfilled**: the asynchronous result has been delivered and ready (`resolve` was called)
5154
- **rejected**: an error was encountered: the promise could not be fulfilled (`reject` was called)
55+
- 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.
5257

5358
## The .then() method
5459

55-
A promise object exposes a `.then()` method through which you can obtain its fulfilled result or an error value in the case the promise was rejected:
60+
A promise exposes a `.then()` method through which you can obtain its fulfilled value or an error value in the case the promise was rejected:
5661

5762
```js
5863
somePromise.then(onFulfilled, onRejected)
5964
```
6065

61-
The `.then()` method takes two **optional** functions (technically they could be called *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:
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:
6267

6368
```js
6469
somePromise.then(onFulfilled)
@@ -70,35 +75,32 @@ If you are only interested in the error case, you can pass `null` for the first
7075
somePromise.then(null, onRejected)
7176
```
7277

73-
or you can use a second method exposed by a promise object, which is just a short-hand for calling `then()` with `null` as its first argument:
78+
or you can use a second method exposed by a promise, which is just a short-hand for calling `then()` with `null` as its first argument:
7479

7580
```js
7681
somePromise.catch(onRejected)
7782
```
7883

79-
It is 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`.
84+
> Note: the callback functions passed as arguments to the `.then()` method are always called asynchronously, even if the promise was already settled.
85+
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`.
8087

8188
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.:
8289

8390
```js
84-
fetchJSON(HYFReposApiEndpoint)
85-
.then(res => getHtmlRepoList(res))
86-
.then(html => renderList($repoList, html))
87-
.catch(() => renderList($repoList,'<li>Error</li>'))
91+
fetchJSON(apiUrl)
92+
.then(data => {
93+
renderData(data);
94+
return fetchJSON(otherUrl);
95+
})
96+
.then(otherData => renderOther(otherData))
97+
.catch(error => handleError(error));
8898
```
8999

90100
Listing 2. Chaining of `then` and `catch`
91101

92-
## Analysis
93-
94-
Let's analyze the code snippet of Listing 2 a bit more in light of what we have discussed up until now.
95-
96-
1. The `getJSON(HYFReposApiEndpoint)` function call returns a promise that will be fulfilled with an array of objects, describing the GitHub repositories of the HackYourFuture organisation.
97-
2. In the first `.then()` the arrow function `res => getHtmlRepoList(res)` takes the place of `onFulfilled` from the discussion above. The *array-of-objects* from step 1 is passed as the `res` parameter and subsequently passed on to the `getHtmlReposList(res)` function call. This function in its turn returns a string of HTML tags, which becomes the fulfillment value of the new promise returned by the first `.then()`.
98-
3. In the second `.then()` the arrow function `html => renderList($repoList, html)` uses the HTML string (the fulfillment value of the first `.then()`) to render the repo data to DOM.
99-
4. The callback function from `.catch()` is only called when one of the promises in the chain is rejected. Otherwise is not called at all.
102+
More information:
100103

101-
See also:
102104
- [MDN - Promise definition](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
103105
- [MDN - Using Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)
104106
- [Promises/A+ specification](https://promisesaplus.com/)

0 commit comments

Comments
 (0)