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: fundamentals/promises.md
+26-3Lines changed: 26 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -91,7 +91,7 @@ somePromise
91
91
92
92
> 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.
93
93
94
-
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 that of the inner promise, when settled. If the function does not return a value, the new promise is immediately fulfilled with the value `undefined`.
94
+
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 outcome is determined by the inner promise, once settled. If the function does not return a value, the new promise is immediately fulfilled with the value `undefined`.
95
95
96
96
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.:
97
97
@@ -114,15 +114,38 @@ Listing 2. Chaining of `then` and `catch`
114
114
115
115
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".
116
116
117
-
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.
117
+
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, there is no way for the `.catch()` at the end of the chain to "see" a `reject()` of the inner promise, leaving the rejection unhandled.
118
118
119
119
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).
120
120
121
121
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*.
122
122
123
123
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.
124
124
125
-
\* Note: `.catch(onRejected)` is a shorthand for `.then(null, onRejected)`.
125
+
Note however that a `.catch()` method does not necessarily have to be the last method in the chain. It can be used to handle errors midway. As mentioned previously, the `.catch()` method returns a new promise which can be used to provide some "fallback" value in case of errors.
126
+
127
+
In the example below a promise is created that (for the purpose of demonstration) is immediately rejected. The promise is subsequently "consumed" twice.
128
+
129
+
1. In the first case ('consumer 1'), the rejection is caught by a `.catch()` method and the rejection value `'bad'` is printed on the console.
130
+
131
+
2. In the second case ('consumer 2'), the rejection is also caught by a `.catch()` method, but now the catch handler completely ignores the rejection value and just returns the fallback value `'good.`. This becomes the fulfillment value of the promise returned by `.catch()`. The next `.then()` in the chain, completely oblivious that an error ever occurred, now prints the fulfillment value `'good'` on the console.
132
+
133
+
```js
134
+
constpromise=newPromise((resolve, reject) => {
135
+
reject('bad');
136
+
});
137
+
138
+
// consumer 1
139
+
promise
140
+
.catch(console.log); // -> "bad"
141
+
142
+
// consumer 2
143
+
promise
144
+
.catch(() =>'good')
145
+
.then(console.log); // -> "good"
146
+
```
147
+
148
+
\* The syntax `.catch(onRejected)` is a shorthand for `.then(null, onRejected)`.
0 commit comments