Prepare for interview ing…… 🌞 If there are mistakes welcome to correct
What is an Event Loop?
Event Loop is the time Loop, which is the mechanism of browser /Node to solve the problem of JavaScript running in a single thread without blocking, which is also the principle of asynchronous.
Event Loop in browser
Let’s start with a problem
console.log('script start');
/ / 1-1
setTimeout(() = > {
console.log('Slim is a cat');
}, 2000);
/ / 2 to 1
Promise.resolve()
.then(function() {
/ / 2-2
console.log('promise1');
}).then(function() {
/ / 2-3
console.log('promise2');
}).finally(() = > {
/ / 2-4
console.log('finally')});/ / 3 to 1
async function foo() {
await bar()
/ / 3 to 2
console.log('async1 end')
}
foo()
/ / 4 to 1
async function errorFunc () {
try {
/ / 4-2
await Promise.reject('error!!! ')}catch(e) {
/ / 4 to 3
console.log(e)
}
/ / 4-4
console.log('async1');
return Promise.resolve('async1 success')
}
errorFunc().then(res= > console.log(res)) / / 4-5
/ / 5-1
function bar() {
console.log('async2 end')}/ / 6-1
console.log('script end');
Copy the code
It’s not a difficult question, and the answer is obvious.
script start
async2 end
script end
promise1
async1 end
error!!!
async1
promise2
finallyAsync1 Success Slime is a catCopy the code
Macro/micro tasks
Let’s do it with a picture
The main thread is a processing line, and the tasks to be executed are the raw materials on the assembly line, which need to be processed one by one. Event loop is the processing workers, and the raw materials that can be directly processed will be processed one by one, which is the synchronous task (macrotask/ macrotask). If the raw materials that need to be pre-processed will be processed according to the type, Back to the pipeline again, this is the asynchronous task (microtask/ microtask).
Common macro tasks: Script entire code, setTimeout, setInterval, setImmediate, I/O, UI Rendering. Common microtasks: process.nexttick (unique to Node), Promise, MutationObserver
Implementation process
- The main thread keeps looping
- The synchronization task creates the execution context and enters the execution stack.
- During the execution of a synchronous task, the system checks whether the executing code has synchronous or asynchronous tasks and puts them in their respective queues.
- After the synchronization task is executed, the system processes the microtasks in the asynchronous task queue and clears the microtasks.
- The microtask queue clears, the next synchronization task enters the execution stack, and the loop repeats.
Start analyzing the above topic
Then we begin to analyze the above problem
- First, print
script start
- Run to 1-1, find the macro task, put into the queue
- Run to 2-1,
Promise.resolve()
Run, back herethen()
Put into the microtask queue - Run to 3-1,
foo()
The function,await bar()
To printasync2 end
, followed by the microtask queue
Await = await = await = await = await = await = await = await = await = await = await
Promise.then((res) = > res).then(() = > { console.log('async1 end')}))Copy the code
- Run to 4-1,
errorFunc()
Run,
await Promise.reject(‘error!!! The following code can be understood as
Promise.then((res) = > res).then(() = > { console.log(e) console.log('async1'); }).then(() = > Promise.resolve('async1 success')) Copy the code
- Run to 6-1 and print
script end
, the main thread completes, and the microtask queue starts to run. - Print 2-2
promise1
Behind,then()
Put into the microtask queue. - Print 3 to 2
async1 end
- Print 4 to 3
error!!!
- Print a 4-4
async1
Behind,then()
Put into the microtask queue. - Print 2 to 3
promise2
- Type 2-4
finally
- Print a 4-5
async1 success
- The microtask queue empties and the main thread pulls the macro task
- Print 1 to 1
Slim is a cat
NodeJS Event Loop
How Node.js works
- The V8 engine parses JavaScript scripts.
- The parsed code calls the Node API.
- The Libuv library is responsible for executing the Node API. It assigns different tasks to different threads, forming an Event Loop that asynchronously returns the execution results of the tasks to the V8 engine.
- The V8 engine returns the results to the user.
Six stages
- Timers: perform
setTimeout
å’ŒsetInterval
In the maturingcallback
. - Pending callback: A small number of pending callbacks in a previous loop
callback
It’s going to be executed in this phase. - Idle, prepare: Used only internally.
- Poll: Gets new I/O events, where node will block under appropriate conditions.
- Check: to perform
setImmediate
The callback. - The close callbacks: execution
socket
çš„close
Event callback.
Process.nextTick()
Process.nexttick () is not shown in the figure, although it is part of the asynchronous API. This is because process.nexttick () is technically not part of the event loop.
When each phase is complete, if there is a nextTick queue, all callback functions in the queue are emptied and executed before other Microtasks.
The title
console.log('start')
setTimeout(() = > {
console.log('timer1')
Promise.resolve().then(function() {
console.log('promise1')})},0)
Promise.resolve().then(function() {
console.log('promise3')})function tick(callback) {
process.nextTick(callback);
}
let cat
tick(() = > {
console.log('name', cat); / / 1
});
cat = 1;
console.log('end')
Copy the code
Result (node > v11)
start
end
name 1
promise3
timer1
promise1
Copy the code
The Event Loop of Node is different from that of the browser
Node
End,microtask
Executes between phases of the event cycle- On the browser side,
microtask
In the event loopmacrotask
Execute after execution