Skip to content

Commit 68d1ac1

Browse files
committed
drafts
1 parent 973f97c commit 68d1ac1

File tree

30 files changed

+454
-259
lines changed

30 files changed

+454
-259
lines changed

1-js/11-async/07-microtask-queue/article.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,62 @@ Naturally, `promise` shows up first, because `setTimeout` macrotask awaits in th
126126

127127
So call have a promise chain that doesn't wait for anything, then things like `setTimeout` or event handlers can never get in the middle.
128128

129+
130+
## Unhandled rejection
131+
132+
Remember "unhandled rejection" event from the chapter <info:promise-error-handling>?
133+
134+
Now, with the understanding of microtasks, we can formalize it.
135+
136+
**"Unhandled rejection" is when a promise error is not handled at the end of the microtask queue.**
137+
138+
For instance, consider this code:
139+
140+
```js run
141+
let promise = Promise.reject(new Error("Promise Failed!"));
142+
143+
window.addEventListener('unhandledrejection', event => {
144+
alert(event.reason); // Promise Failed!
145+
});
146+
```
147+
148+
We create a rejected `promise` and do not handle the error. So we have the "unhandled rejection" event (printed in browser console too).
149+
150+
We wouldn't have it if we added `.catch`, like this:
151+
152+
```js run
153+
let promise = Promise.reject(new Error("Promise Failed!"));
154+
*!*
155+
promise.catch(err => alert('caught'));
156+
*/!*
157+
158+
// no error, all quiet
159+
window.addEventListener('unhandledrejection', event => alert(event.reason));
160+
```
161+
162+
Now let's say, we'll be catching the error, but after an extremely small delay:
163+
164+
```js run
165+
let promise = Promise.reject(new Error("Promise Failed!"));
166+
*!*
167+
setTimeout(() => promise.catch(err => alert('caught')), 0);
168+
*/!*
169+
170+
// Error: Promise Failed!
171+
window.addEventListener('unhandledrejection', event => alert(event.reason));
172+
```
173+
174+
Now the unhandled rejction appears again. Why? Because `unhandledrejection` triggers when the microtask queue is complete. The engine examines promises and, if any of them is in "rejected" state, then the event is generated.
175+
176+
In the example above `setTimeout` adds the `.catch`, and it triggers too, of course it does, but later, after the event has already occured.
177+
129178
## Summary
130179

131180
- Promise handling is always asynchronous, as all promise actions pass through the internal "promise jobs" queue, also called "microtask queue" (v8 term).
132181

133182
**So, `.then/catch/finally` is called after the current code is finished.**
134183

135-
If we need to guarantee that a piece of code is executed after `.then/catch/finally`, it's best to add it into a chained `.then` call.
184+
If we need to guarantee that a piece of code is executed after `.then/catch/finally`, it's best to add it into a chained `.then` call.
136185

137186
- There's also a "macrotask queue" that keeps various events, network operation results, `setTimeout`-scheduled calls, and so on. These are also called "macrotasks" (v8 term).
138187

File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)