Written in the beginning

  1. Eventloop is written in C++, not JS. JS is a single-threaded language that executes tasks as they come in.
  2. The Eventloop mechanism is different in NodeJS and Chrome. Let’s comb through EventLoop in Chrome

Chrome的eventloop

Pre – Knowledge of Chrome

IO thread

The IO thread in the renderer process is dedicated to receiving messages from other processes. Such as:

  1. HTTP response message for a network process
  2. Mouse click message for the main browser process

Timing trigger thread

The timed trigger thread in the renderer process is dedicated to handling setTimeout and setInterval tasks. Add the callback function as a macro task to the renderer’s task queue when the corresponding time is up.

XMLHttpRequest

  • After calling xhr.send(), the renderer sends the request to the network process.
  • After receiving the HTTP response information, the network process submits the message to the renderer process via THE IO thread in IPC mode, and the renderer process adds the XHR callback function to the task queue as a macro task.
  • Execute different callback functions (onError, onReadyStatechange) according to the corresponding state when executing this task.

What are macro tasks and micro tasks

  1. Macro task: Asynchronous task that will be done in a moment
  • SetTimeout and setInterval
  • Script (whole code)
  • requestAnimationFrame
  • Render events (parse DOM, calculate layout, draw)
  • The callback function that the network request completes
  1. Microtasks: Asynchronous tasks with a higher priority
  • Promise.then
  • Promise.catch
  • MutationObserver

Operation mechanism

Execution order

  1. The code inside the script tag as a macro task. Push the global context onto the call stack to start execution.
  2. Execution process: When encountering a macro task, join the macro task queue. When a microtask is encountered, add it to the microtask column of the current macro task. Each macro task creates its own microtask queue.
  3. After the JS synchronization code is executed and before the macro task is about to end, all the tasks of the micro task queue corresponding to the macro task are taken out and executed successively. If another microtask is encountered during execution, join the end of the current microtask queue.
  4. The eventloop ends after the microtask queue clears. Fetching a macro task from the task queue, fetching the code from the macro task, initializing the global context and starting execution. Back to 2.

The instance

setTimeout(() => console.log(4)) 
new Promise(resolve => {  
   resolve() 
   console.log(1) 
}).then(() => { 
   console.log(3) 
}) 
console.log(2)
Copy the code

Output: 1 2 3 (micro task) 4 (macro task)

Advanced topics

async function fn1(){
    console.log(1)
    await fn2()
    console.log(2)
}
async function fn2(){
    console.log(3)
}
fn1()

new Promise(function(resolve){
    console.log(4)
    resolve()
}).then(()=>{
    console.log(5)}
)
Copy the code

Output: 1 3 4 2 5