The subject background

async function async1() {
console.log("async1 start");
await  async2();
 console.log("async1 end");
}
async  function async2() {
 console.log( 'async2');
}
console.log("script start");
setTimeout(function () {
 console.log("settimeout"); }, 0); async1(); new Promise(function (resolve) {
 console.log("promise1");
 resolve();
}).then(function () {
 console.log("promise2");
});
console.log('script end'); 
Copy the code

The essence of the topic is to investigate the implementation sequence of setTimeout, promise, async await and JS time cycle.

Script start async1 start async2 promise1 Script end asynC1 end promise2 setTimeout

Synchronous asynchronous Microtasks and Macrotasks are involved here. Microtasks have a higher priority than Macrotasks, where Microtasks and Macrotasks are:

microtasks:

  • process.nextTick
  • promise
  • Object.observe
  • MutationObserver

macrotasks:

  • setTimeout
  • setInterval
  • setImmediate
  • I/O
  • The UI rendering
  1. An event loop can have one or more task queues.
  2. A Task Queue is a MacroTask Queue
  3. Each event loop has a MicroTask Queue
  4. task queue == macrotask queue ! = microtask queue
  5. A task can be placed in a MacroTask Queue or a MicroTask Queue

So the order of the event loop determines the order in which the JavaScript code is executed. It starts the first loop with script(the whole code). The global context then enters the function call stack. Until the call stack is empty (only global), then all micro-tasks are executed. When all executable micro-tasks have been executed. The loop starts again with macro-Tasks, finds one task queue to complete, and then executes all micro-tasks, and so on.

How is the timer implemented timing? Why does it happen at irregular times?

First, let’s be clear: javascript runs in a single-threaded fashion. The primary purpose of JavaScript is to interact with users and manipulate the DOM. In a multithreaded manner, conflicts can occur. If you have two threads working on a DOM element at the same time, and thread 1 requires the browser to remove the DOM while thread 2 requires the browser to modify the DOM style, the browser cannot decide which thread to use. Of course, we could introduce a mechanism for “locking” the browser to resolve these conflicts, but the complexity is so great that JavaScript has been single-threaded since its birth. Only one specific task can be executed at a time, and other tasks can be blocked. But JavaScript has a model based on “Event Loop” concurrency (not parallelism). The former is logical simultaneity, while the latter is physical simultaneity. Therefore, single-core processors can also achieve concurrency. The figure above illustrates concurrency and parallelism:

Small tips:

console.log(1);
setTimeout(function(){
    console.log(2);
    Promise.resolve(1).then(function(){
        console.log('ok')})})setTimeout(function(){
    console.log(3)
})
Copy the code

Analysis: The default is to push the stack, output 1. There is no microtask, so the microtask will not execute. First go the first setTimeout, output 2, at the same time put the microtask in the queue, execute the microtask, output OK, after the execution of the microtask, then go the macro task, output 3.

Node. Js Event Loop

The V8 engine parses JavaScript scripts. The parsed code calls the Node API. The Libuv library is responsible for executing the Node API. It assigns different tasks to different threads, forming an Event Loop that asynchronously returns the execution results of the tasks to the V8 engine. The V8 engine returns the results to the user.

Introduction to the event loop