JS event loop and task queue (the sequence of macro tasks and micro tasks, the most complete!!!)

The event loop and task queue are high-frequency test points for interviews. This article summarizes the various situations of the task queue.
Let's talk about the event loop first :
because js is running in a single thread, the process can be summarized as:

  • Step 1: The main thread reads the JS code, which is a synchronous environment at this time, forming a corresponding heap and execution stack;
  • Step 2: When the main thread encounters an asynchronous operation, hand over the asynchronous operation to the corresponding API for processing;
  • Step 3: The asynchronous operation is processed and pushed into the task queue
  • Step 4: The main thread queries the task queue, executes microtasks, and executes them in order.
  • Step 5: The main thread queries the task queue, executes microtasks, and executes them in order.
  • Repeat steps four and five;

Next is the focus of this article, the output order of macro tasks and micro tasks in the task queue.

  • First execute the synchronous task in the macro task --> the synchronous task in the micro task --> the asynchronous task in the micro task --> the asynchronous task in the macro task
  • Macro tasks setTimeout setInterval setImmediate also have a sequence of executing setTimeout first and then executing setImmediate I/O UI
  • The microtask promise.then() process.nextTick is executed after promise.then()
new Promise(function (resolve) {
    
    
    console.log('1');
    resolve();
}).then(function () {
    
    
    console.log('2')
})
process.nextTick(function () {
    
    
    console.log('3');
})
setImmediate(() => {
    
    
    console.info('4')        //    1   5   3   2   6   7   10   9   11  4   8   
})
new Promise(function (resolve) {
    
    
    console.log('5');
    resolve();
}).then(function () {
    
    
    console.log('6')
})
setTimeout(function () {
    
    
    console.log('7');
    setImmediate(() => {
    
    
        console.info('8')
    })
    process.nextTick(function () {
    
    
        console.log('9');
    })
    new Promise(function (resolve) {
    
    
        console.log('10');
        resolve();
    }).then(function () {
    
    
        console.log('11')
    })
});

Then there is the relationship between the most critical async function await and the above?

If the await is a promise object, await will suspend the code behind the async function, first execute the synchronization code outside the async function (note that the synchronization code inside the promise will be executed first), wait for the promise object to be fulfilled, and then use the resolve parameter as After the operation result of the await expression is returned, continue to execute the following code in the async function

function sleep(second) {
    
    
    return new Promise((resolve, reject) => {
    
    
    	consol.log('aaaa)
        setTimeout(() => {
    
    
            resolve(' enough sleep~');
        }, second);
    })
}
async function awaitDemo() {
    
    
    let result = await sleep(2000);
    console.log(result);// 两秒之后会被打印出来
}
console.log("主线程1")
awaitDemo();
console.log("主线程2")
//主线程1
//aaaa
//主线程2
//enough sleep~

If await is not a promise, but an expression. await will suspend the execution of the following code in the async function, and execute the synchronous code outside the async function first (note that at this time, the expression after await will be executed first, and then the synchronous code outside the async function will be executed)

function sleep(second) {
    
    
 	return new Promise((resolve, reject) => {
    
    
        setTimeout(() => {
    
    
            resolve(' enough sleep~');
        }, second);
    })
}
function normalFunc() {
    
    
    console.log('normalFunc');
}
async function awaitDemo() {
    
    
    await normalFunc();
    console.log('something, ~~');
    let result = await sleep(2000);
    console.log(result);// 两秒之后会被打印出来
}
console.log("主线程1")
awaitDemo();
console.log("主线程2")
//主线程1
//normalFunc
//主线程2
//something, ~~
//enough sleep~

The difficulty that should be out is that there are so many situations, it should not be more difficult (maybe I am still a novice, with little knowledge). If there is a mistake, criticism and correction are welcome.

Guess you like

Origin blog.csdn.net/m0_59722204/article/details/128942198