A, an overview of

Event Loop is an execution model that browsers and NodeJS implement based on different technologies.

1. Event Loop of the browser

The browser’s Event Loop is in the HTML 5 specification (reference: html.spec.whatwg.org/multipage/w… Loop model, the specific implementation process of the browser manufacturers.

2. NodeJS的Event Loop

NodeJS Event Loop is based on Libuv (cross-platform asynchronous IO library) implementation. You can refer to the Node documentation and libuv documentation. Libuv already implements Event Loop (see github.com/libuv/libuv…

EventLoop in Node

See also: juejin. Cn/post / 692169…

EventLoop for browser

1. Learn a few concepts from the picture above

Function call stack: The task (code) is executed in the function call stack; Corresponds to Stack in the figure above

Queues (macro queues, microqueues) : Used to manage the order in which tasks (code) are executed. Corresponding to the Task Queue and Microtask Queue in the figure above

Background Threads: Browser timer trigger thread, HTTP asynchronous request thread…. The equivalent thread is used to process the corresponding event code; Corresponds to Background Threads in the figure above. SetTimeout is executed by the timer thread, and the corresponding callback function is pushed into the macro task and eventually executed in the function call stack. The HTTP asynchronous request is executed by the HTTP asynchronous request thread, and the corresponding callback function is pushed into the macro task, which also ends up executing…. in the function call stack

Function call stacks are used to execute code, queues are used to control the order of code execution, and browser threading modules are used to handle events.

2. Macro queues and microqueues

Macro queues, macro tasks, macroTasks, also called tasks. Callbacks from asynchronous tasks are placed in the Macro Task Queue, waiting to be called later.

  • setTimeout
  • setInterval
  • RequestAnimationFrame (browser only)
  • I/O
  • UI Rendering (browser only)

Microqueues, microtasks, microtasks, also called jobs. Other asynchronous tasks whose callbacks go to the Micro Task Queue, waiting to be called later, include:

  • Promise
  • Object.observe
  • MutationObserver

3. Summary of macro and micro tasks

  1. Perform macro tasks first, then micro tasks; Then perform the macro task…. Macro tasks and micro tasks are executed in alternating cycles.
  2. When a macro task is executed, a new macro task is created and placed in the macro task queue, and a new micro task is created and placed in the task queue of the micro task.
  3. Macro tasks are executed one by one; After executing a macro task, all microtasks generated in this round are executed.

Example 4.

The following is a detailed analysis of the execution process and order of the browser through an example combined with the above picture and summary

setTimeout(() = >{
    console.log("5.setTimeout1");
    Promise.resolve().then(data= > {// Put the microtask queue (flag 5)
        console.log(6);
    });
}, 100); // Execute to this setTimeout browser will give it to the setTimeout module to execute (flag 3), execute after 100ms and then put the callback into the macro task queue (flag 4).
console.log(0) // The synchronization task is output immediately
setTimeout(() = >{ / / same as above
    console.log("4.setTimeout2");
});
new Promise((resolve, reject) = > {
    console.log('1.new promise') // New Promise is that the synchronization task itself will execute immediately, so console will output immediately
    resolve('2.new promise resolve')
}).then(res= > { // The resolve task will be placed in the microtask queue (tag 1)
    console.log(res) 
})
Promise.resolve().then(data= >{// Put the microtask queue (tag 1)
    console.log(3); 
});

Copy the code

The macro task queue is identified by []. Microtask queues are identified by []

The whole JS code can be regarded as a macro task, and the macro task queue is the whole JS code.

  1. Execute the macro task, the whole JS code, into the function call stack to execute
  2. When setTimeout is encountered, hand it over to the setTimeout module to manage (tag 3).
  3. When console.log(0) is encountered, the synchronization code is printed immediately
  4. When setTimeout is encountered, hand it over to the setTimeout module to manage (tag 3). After 0ms, the setTimeout module will put the setTimeout callback into the macro task queue (flag 4); Now the macro task queue is setTimeout callback.
  5. If a new Promise is encountered, console.log(‘1.new Promise ‘) will output the synchronization task immediately, and the resolve task will be placed on the microtask queue (tag 1) [Promise]
  6. If promise.resolve ().then is encountered, it is placed on the microtask queue (tag 1) [Promise, Promise]
1. New promise [promise, promise]Copy the code
  1. Perform microtasks: After performing the above macro tasks, start executing the microtasks generated by this round of macro tasks, namely two [Promise, Promise]
2. New promise resolve 3 //Copy the code
  1. Execute macro task: continue to execute macro task after executing microtask [setTimeout callback]
4. SetTimeout2 // Macro task [] microtask []Copy the code
  1. The program waited for 100ms… After; The browser setTimeout module puts the setTimeout callback into the macro task queue (flag 4); Now the macro task queue is setTimeout callback.
  2. Console. log(” 5.settimeout1 “) The synchronization task will be executed immediately; If promise.resolve ().then is encountered, it will be placed on the microtask queue (tag 1) [Promise]
  3. Perform microtasks [Promise]
New promise 2. New Promise resolve 3 4. SetTimeout2 5Copy the code