preface

A few days ago, I was curious about the Event Loop in the browser while understanding node’s Event Loop mechanism. We all know that javascript is single-threaded, and tasks need to be executed sequentially, one by one. If javascript had two threads, one to style the DOM and the other to delete the DOM, it would be confusing. Single threading saves memory, but must wait for the previous task to complete before the next task can be executed. To understand the Event Loop in the browser, take a look at this diagram:

The heap and the stack

The heap is an area of memory that is actively requested by the user, such as new Object(), which stores an Object in the heap. A stack is an area of memory temporarily occupied by functions that are stored on the stack.

Event Loop implementation process

In the previous picture:

  1. All synchronization tasks are executed on the main thread, forming an execution stack;
  2. Whenever an asynchronous task has a result, an event is placed in the Task queue (queue is a first-in, first-out data structure, stack is a first-in, last-out data structure);
  3. Once all synchronous tasks in the execution stack are completed, the system reads the task queue and puts the events in the queue into the stack for execution in sequence, which is to execute the callback functions in asynchronous tasks. This is an Event Loop;

Macro and micro tasks

In the previous figure, we can see that there are also macrotasks and microtasks.

MacroTask setTimeout setInterval

MicroTask Promise. Then MessageChannel MicroTask (Implementation principle of nextTick in VUE)

Synchronous tasks are executed first, microtasks are put on the execution stack and microtasks are executed first, then macro tasks,

Take a look at the picture below (personal understanding)

For example

console.log(1);
setTimeout(function(){
    console.log(2);
    new Promise(function(resolve,reject){
        console.log('promise');
        resolve();
    }).then(res=>{
        console.log('promise.then'); })});setTimeout(function(){
        console.log(4);
    })
console.log(5);
Copy the code

Place this line of code in the browser console

Analyze:

  • Log (1) and console.log(5) are used to perform synchronization tasks in the stack.
  • This is followed by putting their callbacks into MacroTask when setTimeout is encountered;
  • Console. log(2) is executed, then promise is immediately executed, then promise. Then the microtasks are placed in the MicroTask directly connected to the stack and executed first.
  • Finally, the second setTimeout callback is console.log(4);

Node. Js Event Loop

The Event Loop in a browser is different from the Event Loop in a Node.

In the Node environment, the execution stack will execute the current task queue first, i.e., the callback function of the two setTimeout functions, before executing our microtask queue, i.e., promise. Then is the last execution, isn’t it strange?

See the schematic below (author @Busyrich).

Note that Node adds one mediate task (process.nextTick) and one setImmediate task (Mediate).

To put it simply, a Node processing an execution queue will finish executing the current queue anyway, then empty the microtask queue before moving on to the next queue.

Without further ado, go straight to the picture above (personal understanding).

This should make sense. Finally, notice that process.nextTick is faster than promise.then in microtasks

Inadequate level, you are welcome to correct.

The resources

More on the Event Loop