Introduction:
JavaScript is a single-threaded language (in layman’s terms, one thing at a time). Asynchronous operations are placed in an event loop queue, waiting for the main execution stack to execute. There is no dedicated asynchronous execution thread.
How do we explain that we can only do one thing at a time?
Ask questions
<! -- omitted CSS section --><body>
<section>
<div class="process" id="process-one"></div>
<div class="process" id="process-two"></div>
<button onclick="start()" style="margin-top: 20px">start</button>
</section>
</body>
<script>
function handle(dom) {
let i = 0;
(function run() {
dom.innerHTML = i
dom.style.width = i + The '%'
if (++i <= 100) {
setTimeout(run, 50()})}})let processOne = document.getElementById('process-one')
let processTwo = document.getElementById('process-two')
function start(){
handle(processOne)
handle(processTwo)
}
</script>
Copy the code
You can see that when you click the Start button, both progress bars load simultaneously, right?
Let’s explain this phenomenon perfectly through the following study.
Noun explanation
Before we explain this list of terms let’s look at a picture
It can be roughly divided into four modules:
Execute the Stack
The main thread code is preferentially executed. When all the main thread codes are executed, the tasks in the microtask queue are preferentially taken from the task queue. When all the microtask queues are executed, the tasks in the macro task queue are preferentially taken from the macro task queue
Note: if a microtask is generated during the execution of the macro task, the microtask code will be executed first
MacroTasks
Mainly include:
Script (whole code)
setTimeout
.setInterval
.setImmediate
.I/O
.ui rendering
In the new standard it is called Task
Microtasks
Mainly include:
process.nextTick
(NodeJs)Promise
MutationObserver
(New HTML5 features)
It’s called Jobs in the new standard
Time module
SetTimeout and setInterval are used to read seconds
Code execution
So much for the conceptual stuff, let’s explain the whole event polling mechanism with code and images
Write the output order based on the code in the stack below
Write down the specific process below:
- Execute code ① to print 1
- Execute code ②, will
setTimeout
Insert the Time module to start reading seconds (the current Time is 0, in modern browsers, at least 4ms, that is, even if the writing is 0, there will be 4ms of reading seconds). - Execute code ③, the Promise is the microtask, and put it into the microtask queue.
- Execute code ④ and print 4
- At this point, all synchronous tasks are completed, and asynchronous tasks are started. First, the micro task callback function of the first micro task is put into the execution stack to continue execution
- Execute the callback function of code block ③ to print print 3
- At this point, the synchronization task is all executed, and it continues to fetch from the microtask. At this point, the microtask queue is empty, and the time loop mechanism will fetch from the macro task and put the callback function of code block ② into the execution stack
- Execute the callback function of the code block ② taken from the macro task to print print 2
Final result: 1, 4, 3, 2
So what is the Event Loop mechanism? The mechanism by which the above process is actually executed repeatedly is called Event Loop.
Knowing the above process, congratulations, the whole event polling mechanism is that simple
Now let’s look at some of the things that we need to remember
Timing module running time
setTimeout(function(){
// How many seconds will it take for the program to arrive here
}, 1000)
JSON.parse('./index.json') // Suppose the parsing takes 5 seconds
Copy the code
Here are some simple explanations: SetTimeout will start reading seconds after it is put into the Time module, so it is not read seconds after JSON parsing 5, but before JSON parsing. Therefore, after JSON execution is completed, setTimeout reading seconds will already be counted. The callback function is placed in the macro task queue and will be executed immediately
Macro tasks contain microtasks
Let’s look at the macro task with a microtask in it. After looking at the example above, try writing the following output:
console.log(1)
setTimeout(() = > {
console.log(2)
Promise.resolve().then(() = > {
console.log(3)})})new Promise((resolve, reject) = > {
console.log(4)
resolve(5)
}).then((data) = > {
console.log(data);
return 6;
}).then((data) = >{
console.log(data)
})
setTimeout(() = > {
console.log(7);
})
console.log(8);
Copy the code
See which of the following is your answer (A/B)
A: 1,4,8,5,6,2,3,7
B: 1,4,8,5,6,2,7,3
If it’s neither A nor B, then congratulations, go back to the top of the article and read it again
The only thing that might confuse you here is the order of 3 and 7
In simple terms, during the execution of the macro task, a microtask is generated. Should we continue to process the subsequent macro task or process the microtask first?
Want to understand this, actually very simple, here to remember a word: all asynchronous task in the implementation process, from the asynchronous task queue callback function got the task to perform in the stack, after performing the task stack code, at this time will continue in accordance with the previous way, from micro tasks first, and then taken from the macro task
In the code above, the setTimeout callback function generates a microtask when it is put into the execution stack. After the execution stack is completed, the event loop mechanism will first go to the microtask queue to get the task to execute according to the agreed steps.
So the correct answer is: A
After understanding the whole Event Loop, it is actually not difficult. Write down a simple summary to deepen the impression!