javascript

0. Preface:

Recently, I wrote some asynchronous recursive code, which was really a headache, so I restudied the sequence of JavaScript code execution, and attached an interview question parsing.

1. Sequence of JavaScript code execution

Let’s start with a couple of concepts

1.1 Micro/macro tasks

Asynchronous queues include: micro-tasks and macro-tasks

NextTick, Promise (process.nextTick is unique to Node)

Macro tasks include: Script, setTimeout, setInterval, setImmediate, I/O, UI Rendering

Tips:

  • Microtasks take precedence over macro tasks only if the synchronization code has already been executed. becausescriptIt is a macro task, and the program starts with the synchronization script, i.escript
  • PromiseThe code inside is synchronous code,.then()Is asynchronous code.

1.2 Event Loop

An Event Loop is a program structure for waiting and sending messages and events.

The order of Event Loop execution is as follows:

  • Start by synchronizing the code (macro task)
  • When all synchronous code has been executed, the execution stack is empty, and the query is made to see if any asynchronous code needs to be executed
  • Perform all microtasks
  • When all the microtasks are done, the page is rendered if necessary
  • Then start the next Event Loop, which executes the asynchronous code in the macro task, i.esetTimeoutThe callback function in

Perform one macro task (script synchronization code), then execute and empty the microtask, then perform another macro task, then execute and empty the microtask, then perform another macro task, then execute and empty the microtask…… Repeat (one macro task -> Clear microtask -> one macro task -> Clear microtask)

Order of javascript code execution

2. Detailed explanation of interview questions

2.1 the topic

setTimeout(function ({

  console.log(" set1");

  new Promise(function (resolve{

    resolve();

  }).then(function ({

    new Promise(function (resolve{

      resolve();

    }).then(function ({

      console.log("then4");

    });

    console.log("then2 ");

  });

});



new Promise(function (resolve{

  console.log("pr1");

  resolve();

}).then(function ({

  console.log("then1");

});



setTimeout(function ({

  console.log("set2");

});



console.log(2);



new Promise(function (resolve{

  resolve();

}).then(function ({

  console.log("then3");

});

Copy the code

2.2 Performing Process Analysis

Execute all synchronized code (first macro task) :

setTimeout(function (// setTimeout function into the macro task

  console.log(" set1");

  new Promise(function (resolve{

    resolve();

  }).then(function ({

    new Promise(function (resolve{

      resolve();

    }).then(function ({

      console.log("then4");

    });

    console.log("then2 ");

  });

});



new Promise(function (resolve{

  console.log("pr1"); // The code inside the Promise executes pr1 directly

  resolve();

}).then(function ({

  console.log("then1"); // promise. then put the microtask

});



setTimeout(function ({

  console.log("set2"); // setTimeout function into the macro task

});



console.log(2); / / print 2



new Promise(function (resolve{

  resolve();

}).then(function ({

  console.log("then3"); // promise. then put the microtask

});





// The console prints pr1 > 2

// Asynchronous task queue: [micro task number :2][macro task number :2]

// Perform and clear microtasks

Copy the code

Perform and clear microtasks

function ({

  console.log("then1");  / / output then1

}



function ({

  console.log("then3"); / / output then3

}



// The console prints then1 > then3

// Asynchronous task: [micro task :0][macro task: 2]

// Perform a macro task

Copy the code

Perform a macro task

function ({

  console.log(" set1");   / / print characters

  new Promise(function (resolve{

    resolve();

  }).then(function ({     // promise. then put the microtask

    new Promise(function (resolve{

      resolve();

    }).then(function ({

      console.log("then4");

    });

    console.log("then2 ");

  });

}



// The console prints: set1

// Asynchronous task: [micro task :1][macro task :1]

// Perform and clear microtasks

Copy the code

Perform and clear microtasks

function ({     

    new Promise(function (resolve{

      resolve();      

    }).then(function ({

      console.log("then4");   // promise. then put the microtask

    });

    console.log("then2 ");    / / print then2

}



// At this point the console prints: then2

// Asynchronous task: [micro task :1][macro task :1]

// The list of microtasks has not been cleared

Copy the code

At this time, the increase of the microtask list is not cleared, and the microtask continues to be executed

function ({

      console.log("then4");   / / print then4

}



// At this point the console prints: then4

// Asynchronous task: [micro task :0][macro task: 1]

// Execute the macro task

Copy the code

Executing macro tasks

function ({

  console.log("set2"); / / print set2

}

// The console prints: set2

// Asynchronous task: [micro task :0][macro task :0]

// End of program

Copy the code

Complete input sequence

pr1

2

then1

then3

set1

then2 

then4

set2

Copy the code

Recommended reading

  • A simple answer to This question

  • How to use anti-shake and throttling elegantly in Vue

  • How to use Async correctly in array.foreach

  • How to use Async correctly in array.filter

  • How to use Async correctly in array.reduce

If it helps you a little bit, you can like, like and favorites.

The shadow of Perso (^_-)