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/11-async/07-microtask-queue/article.md
+11-9Lines changed: 11 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -3,9 +3,9 @@
3
3
4
4
Promise handlers `.then`/`.catch`/`.finally` are always asynchronous.
5
5
6
-
Even when a Promise is immediately resolved, the code on the lines *below*your `.then`/`.catch`/`.finally` will still execute first.
6
+
Even when a Promise is immediately resolved, the code on the lines *below*`.then`/`.catch`/`.finally` will still execute before these handlers .
7
7
8
-
Here's the code that demonstrates it:
8
+
Here's the demo:
9
9
10
10
```js run
11
11
let promise =Promise.resolve();
@@ -21,7 +21,7 @@ That's strange, because the promise is definitely done from the beginning.
21
21
22
22
Why did the `.then` trigger afterwards? What's going on?
23
23
24
-
# Microtasks
24
+
##Microtasks
25
25
26
26
Asynchronous tasks need proper management. For that, the standard specifies an internal queue `PromiseJobs`, more often referred to as "microtask queue" (v8 term).
27
27
@@ -54,9 +54,11 @@ Now the order is as intended.
54
54
55
55
## Event loop
56
56
57
-
In-browser JavaScript, as well as Node.js, is based on an *event loop*.
57
+
In-browser JavaScript execution flow, as well as Node.js, is based on an *event loop*.
58
58
59
-
"Event loop" is a process when the engine sleeps and waits for events, then reacts on those and sleeps again.
59
+
"Event loop" is a process when the engine sleeps and waits for events. When they occur - handles them and sleeps again.
60
+
61
+
Events may come either comes from external sources, like user actions, or just as the end signal of an internal task.
60
62
61
63
Examples of events:
62
64
-`mousemove`, a user moved their mouse.
@@ -120,14 +122,14 @@ Promise.resolve()
120
122
121
123
Naturally, `promise` shows up first, because `setTimeout` macrotask awaits in the less-priority macrotask queue.
122
124
123
-
As a logical consequence, macrotasks are handled only when promises give the engine a "free time". So if we have a promise chain that doesn't wait for anything, then things like `setTimeout` or event handlers can never get in the middle.
125
+
As a logical consequence, macrotasks are handled only when promises give the engine a "free time". So if we have a chain of promise handlers that don't wait for anything, execute right one after another, then a `setTimeout`(or a user action handler) can never run in-between them.
124
126
125
127
126
128
## Unhandled rejection
127
129
128
130
Remember "unhandled rejection" event from the chapter <info:promise-error-handling>?
129
131
130
-
Now, with the understanding of microtasks, we can formalize it.
132
+
Now we can describe how JavaScript finds out that a rejection was not handled.
131
133
132
134
**"Unhandled rejection" is when a promise error is not handled at the end of the microtask queue.**
Now the unhandled rejection 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.
172
+
Now the unhandled rejection appears again. Why? Because `unhandledrejection`is generated when the microtask queue is complete. The engine examines promises and, if any of them is in "rejected" state, then the event triggers.
171
173
172
174
In the example, the `.catch` added by `setTimeout` triggers too, of course it does, but later, after `unhandledrejection` has already occurred.
173
175
174
176
## Summary
175
177
176
178
- Promise handling is always asynchronous, as all promise actions pass through the internal "promise jobs" queue, also called "microtask queue" (v8 term).
177
179
178
-
**So, `.then/catch/finally` are called after the current code is finished.**
180
+
**So, `.then/catch/finally`handlers are called after the current code is finished.**
179
181
180
182
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.
0 commit comments