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, printscript 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 printscript end, the main thread completes, and the microtask queue starts to run.
  • Print 2-2promise1Behind,then()Put into the microtask queue.
  • Print 3 to 2async1 end
  • Print 4 to 3error!!!
  • Print a 4-4async1Behind,then()Put into the microtask queue.
  • Print 2 to 3promise2
  • Type 2-4finally
  • Print a 4-5async1 success
  • The microtask queue empties and the main thread pulls the macro task
  • Print 1 to 1Slim 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: performsetTimeout å’Œ setIntervalIn the maturingcallback.
  • Pending callback: A small number of pending callbacks in a previous loopcallbackIt’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 performsetImmediateThe callback.
  • The close callbacks: executionsocket çš„ closeEvent 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

  • NodeEnd,microtaskExecutes between phases of the event cycle
  • On the browser side,microtaskIn the event loopmacrotaskExecute after execution