js event loop -- look at the output order

js event loop:

Because js is single threaded, it can only do one thing at a time. When the current hosting environment is browser, if a task takes too long, it will lead to page blocking. Therefore, there is the js event loop mechanism, which divides tasks into synchronous tasks and asynchronous tasks. The synchronous tasks are continuously executed in the main thread, and the asynchronous tasks enter the task queue. When the main stack is empty after the synchronous tasks are executed, they go to the task queue to read the asynchronous task execution. This continuous loop process is called event loop.

1.promise:

The micro task enters the micro task queue and is executed in this round of event cycle, for example:

new Promise(function(resolve) {
    console.log('promise');
}).then(function() {
    console.log('then');
})

new Promise Immediately, then Distribute functions to micro tasks Event Queue. 

Points needing attention

1.promise.then is used to specify the callback function for the success or failure of the promise object. Therefore, it will be executed only when the promise object is in the state of completed or rejected. Otherwise, it will not be executed:

const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('success')
    }, 1000)
})
const promise2 = promise1.then(() => {
    throw new Error('error!!!')
})
 
console.log('promise1', promise1)
console.log('promise2', promise2)
 
setTimeout(() => {
    console.log('promise1', promise1)  
    console.log('promise2', promise2)
}, 2000)



The results are:

 2. Promise. The return value of then is a promise object. When the return value of the callback function is a promise object, a new promise value is obtained as the returned promise result value; If the return value is a general value, take this value as the return promise result value.

Promise.resolve(1)
    .then((res) => {
        console.log(res)
        return 2
    })
    .catch((err) => {
        return 3
    })
    .then((res) => {
        console.log('Yes');
        console.log(res)
    })

Output in sequence: 1, executed, 2

3.promise has three states: pending, fulfilled and rejected. The state can only be changed once

const promise = new Promise((resolve, reject) => {
    resolve('success1')
    reject('error')
    resolve('success2')
})
promise
.then((res) => {
    console.log('then: ', res)
})
.catch((err) => {
    console.log('catch: ', err)
})

Code output: success1,then:success1

2.setTimeout:

Macro task: enter the macro task queue and execute in the next round of event cycle, for example:

setTimeout(() => {
    task();
},3000)
console.log('implement console');

//Execute console
//task()

3.async/await:

async declares an asynchronous function, which returns a promise object. If the returned object is not promise, promise will be used automatically Resolve() wrapper, for example:

async function test(){
    return 'test'
}
test()

The return value is Promise{<resolved>:"test"}

await waits for the result of the expression on the right, which is a promise object or other value.

function test(){
    return new Promise(resolve=>{
        setTimeout(()=>resolve('test'),2000);
    });
}

const result=await test();
console.log(result);
console.log('end');

console.log('end')Will wait until two seconds

Because await will block the following code, in order to avoid blocking, await must be used in async function, and async function calls will not cause blocking.

function test(){
    return new Promise(resolve=>{
        setTimeout(()=>resolve('test'),2000);
    });
}

async function test2(){
    const result=await test();
    console.log(result);
}
test2();
console.log('end');

Execute first console.log('end'),Execute in two seconds console.log('test')

Execution sequence of async/await: if await is encountered, the following code will be blocked. First execute the synchronization code outside async. After the synchronization code is executed, return to async and continue to execute the code behind await. (that is, await will only block the code in the current async method and will not affect the execution of external code)

Above code output:

1. First execute the macro task, execute the test1 function, console log('start test1'); When await is encountered, execute console log('test2')

2. Execute console log('start async');

3. Enter the macro task queue when setTimeout is encountered

4. Execute new Promise, print promise 1 then enters the micro task queue

5. Execute console log('end async');

6. After the synchronization code outside test1() is executed, return to test1() and execute console Log (await test2()) returns promise {< resolved >:'return test2 value '} and pushes it into the micro task queue

7. At this time, the first macro task ends and all micro tasks are executed. Because the micro task queue is first in first out, the console is executed first Log ('promise2 '), and then execute console log('return test2 value')

8. After executing test2, the following code is no longer blocked, and execute console log('end test1');

9. Execute the next macro task, namely console log('setTimeout');

 

 

Keywords: Javascript

Added by kidestranged on Sun, 19 Dec 2021 15:59:34 +0200