nodejs -- browser event ring - macro task and micro task

1.JS is single threaded

   The code in JS is serial,   The previous execution is not completed, and the later cannot be executed

2. Execution sequence

  • The program will execute all synchronization codes from top to bottom
  • If asynchronous code is encountered during execution, the asynchronous code will be placed in the event loop
  • When all synchronization code is executed,   JS will continuously detect   Whether the asynchronous code in the event loop meets the condition
  • Once the condition is met, the asynchronous code that meets the condition is executed

3. Macro and micro tasks:

In the asynchronous code of JS, it distinguishes between "macro task" and "micro task"

Macro task:   Macro / big,   It can be understood as a time-consuming and slow task

Microtask:   Micro / small meaning,   It can be understood as a relatively less time-consuming and less slow task

4. Common macro tasks and micro tasks:

MacroTask:   setTimeout,   setInterval,   setImmediate (IE only)

Basic usage of setlmmediate:

setImmediate(function() {
            console.log("setImmediate");
        });
console.log("Synchronization code Start");
console.log("Synchronization code End");

 

 

setImmediate and setTimeout,   setInterval difference:

setImmediate cannot set the delay time,   And can only be executed once; Ie is unique, that is, it can only take effect in IE browser

MicroTask:   Promise,   MutationObserver  , process.nextTick (unique to node)  ...

Basic usage of MutationObserver:

MutationObserver is specifically used to listen for changes in nodes

<div></div>
<button class="add">Add node</button>
<button class="del">Delete node</button>
        let oDiv = document.querySelector("div");
        let oAddBtn = document.querySelector(".add");
        let oDelBtn = document.querySelector(".del");
        oAddBtn.onclick = function() {
            let op = document.createElement("p");
            op.innerText = "I'm a paragraph";
            oDiv.appendChild(op);
        }
        oDelBtn.onclick = function() {
            let op = document.querySelector("p");
            oDiv.removeChild(op);
        }

        //Listen -- as long as you listen to the node you add or delete, the following statement will be printed
        let mb = new MutationObserver(function() {
            console.log("Yes");
        });

        //Select the object to listen to
        // This means listening for changes in oDiv child nodes
        mb.observe(oDiv, {
            "childList": true
        });

        console.log("Synchronization code Start");
        console.log("Synchronization code End");

Note:  

  • All macro tasks and micro tasks will be placed in their own execution queue,   That is, there is a macro task queue and a micro task queue
  • All tasks placed in the queue adopt the "first in first out" principle,   That is, multiple tasks meet the conditions at the same time,   Then it will be executed first and put in first

5. Complete execution sequence

  • Execute all synchronization codes from top to bottom
  • Macro tasks encountered during execution are placed in the macro task queue, and micro tasks encountered are placed in the micro task queue
  • When all synchronization code is executed,   Execute all callbacks that meet the requirements in the micro task queue
  • After all callbacks meeting the requirements of the micro task queue are executed,   Execute all callbacks in the macro task queue that meet the requirements
  • ... ...

Example,

        // 1. Define a macro task
        setTimeout(function() {
            console.log("setTimeout1");
        }, 0);

        // 2. Define a micro task
        Promise.resolve().then(function() {
            console.log("Promise1");
        });

        console.log("Synchronization code Start");

        Promise.resolve().then(function() {
            console.log("Promise2");
        });

        setTimeout(function() {
            console.log("setTimeout2");
        }, 0);

        console.log("Synchronization code End");

 

 

Execution process:

 

Note:

Every time a macro task is executed, it will immediately check whether the micro task queue has been emptied,   If not, empty it immediately

Example,

        // 1. Define a macro task
        setTimeout(function() {
            console.log("setTimeout1");
            // 2. Define a micro task p1
            Promise.resolve().then(function() {
                console.log("Promise1");
            });
            // 2. Define a micro task p2
            Promise.resolve().then(function() {
                console.log("Promise2");
            });
        }, 0);

        // 1. Define a macro task
        setTimeout(function() {
            console.log("setTimeout2");
            // 2. Define a micro task p3
            Promise.resolve().then(function() {
                console.log("Promise3");
            });
            // 2. Define a micro task p4
            Promise.resolve().then(function() {
                console.log("Promise4");
            });
        }, 0);

 

Execution process:

 

 

Example 2,

         // 1. Define a macro task
        setTimeout(function() {
            console.log("setTimeout1");
            // 2. Define a micro task p2
            Promise.resolve().then(function() {
                console.log("Promise2");
            });
            // 2. Define a micro task p3
            Promise.resolve().then(function() {
                console.log("Promise3");
            });
        }, 0);
        // 2. Define a micro task p3
        Promise.resolve().then(function() {
            console.log("Promise1");
            // s2
            setTimeout(function() {
                console.log("setTimeout2");
            });
            // s3
            setTimeout(function() {
                console.log("setTimeout3");
            });
        });

 

Execution process:

 

 

 

Keywords: node.js

Added by az_wraith on Wed, 22 Sep 2021 09:13:28 +0300