当前位置:网站首页>Explanation of JS event loop mechanism and asynchronous tasks

Explanation of JS event loop mechanism and asynchronous tasks

2022-06-13 08:32:00 SwJieJie

We said to the JS At the same time, I have to mention the browser's event loop mechanism

1. Browser's event loop mechanism

1.1 The sequence of events

(1), When the event begins , First of all JS Main thread mechanism , because JS It belongs to the single thread mechanism , Therefore, when there are multiple tasks, there will be waiting , Wait for the event that first enters the thread to be processed

(2), This will lead to waiting , If the previous event is not completed , Later events will be waiting

(3), But it's similar to AJAX and setTimeout , setInterval Waiting Events , There is asynchronous processing

(4), By handing asynchronous events to asynchronous modules , The main thread will process the following events in parallel

(5), When the main thread is idle , Asynchronous processing completed , The main thread will read the data returned by the asynchronous processing callback Perform subsequent operations for asynchronous events

Synchronous execution means that the main thread follows the sequence of events , Execute events in sequence
Asynchronous execution means that the main thread skips the wait first , Execute the following events , Asynchronous events are handled by asynchronous modules

As shown in the figure : Explain the task execution process of synchronous execution and asynchronous execution .
 Insert picture description here
1, The event begins , Enter the main thread
2, If the main thread finds an asynchronous event , Hand over asynchronous events to asynchronous modules , The main thread continues to execute the following synchronization events
3, When the asynchronous process is completed , Back in the event queue
4, Main thread execution completed , Will query the event queue , If there are events in the event queue , The event queue pushes the event to the main thread
5, The main thread executes the events pushed from the event queue , After execution, query in the event queue … The process of this cycle is the event cycle

1.2 Asynchronous tasks are divided into macro tasks (macrotask) And micro tasks (microtask)

Common macro tasks :setTimeout setInterval I/O script

Common micro tasks :promise

In the same event cycle , Micro tasks always precede macro tasks
In the same event cycle , Micro tasks always precede macro tasks
In the same event cycle , Micro tasks always precede macro tasks

(** Important things are to be repeated for 3 times !)

Case list :1

console.log(1)
setTimeout(() => {
    
    console.log(2)
}, 0)

Promise.resolve().then(()=> {
    
    console.log(3)
})
console.log(4)

//  result  1 4 3 2

1, The task begins , Enter the execution stack . encounter console.log(1), It's a synchronization task , Output 1;
2, The execution stack continues to execute , Encounter timer setTimeout, It's an asynchronous macro task , Enter the macro task queue of the asynchronous process ;
3, The execution stack continues to execute , encounter Promise, It's an asynchronous micro task , Enter the micro task queue of the asynchronous process ;
4, The execution stack continues to execute , encounter console.log(4), It's a synchronization task , Output 4;
5, Synchronization task execution completed , Start querying the task queue , The micro task queue is before the macro task queue , Execute the micro task queue output first 3;
4, The micro task queue has been executed , Then query the macro task queue , Output 2, At this point, the whole task queue is completed , The final output 1 4 3 2

Case list :2

 setTimeout(function(){
    
     console.log(' The timer is on ')
 });
 
 new Promise(function(resolve){
    
     console.log(' Do it now for It's a cycle ');
     for(var i = 0; i < 10000; i++){
    
         i == 99 && resolve();
     }
 }).then(function(){
    
     console.log(' perform then Function ')
 });
 
 console.log(' End of code execution ');
  result : Do it now for It's a cycle  ---  End of code execution  ---  perform then Function  ---  The timer is on 

1, First, execute script Macro task under , encounter setTimeout, Put it in the 【 queue 】 in
2, encounter new Promise Direct execution , Print " Do it now for It's a cycle "
3, encounter then Method , It's a micro task , Put it in the 【 In the queue 】
4, Print “ End of code execution ”
5, This round of macro task is completed , View this round of micro tasks , Found a then Functions in methods , Print " perform then Function "
Here we are , The current round event loop Complete .
6, In the next cycle , Execute a macro task first , Found macro task's 【 queue 】 There's one in it setTimeout The function in , Execution printing " The timer is on "

Case list :3

console.log(1)
setTimeout(() => {
    
    console.log(2)
}, 0)

new Promise((resolve) => {
    
    console.log(3)
    resolve(4)
}).then((res)=> {
    
    console.log(res)
})
console.log(5)

//  The final results  1 3 5 4 2

Case list :4

setTimeout(() => console.log('setTimeout1'), 0) //1 Macro task 
setTimeout(() => {
    								//2 Macro task 
    console.log('setTimeout2')
    Promise.resolve().then(() => {
    
        console.log('promise3')
        Promise.resolve().then(() => {
    
            console.log('promise4')
        })
        console.log(5)
    })
    setTimeout(() => console.log('setTimeout4'), 0)  //4 Macro task 
}, 0)
setTimeout(() => console.log('setTimeout3'), 0)  //3 Macro task 
Promise.resolve().then(() => {
    //1 Micro task 
    console.log('promise1')
})

//  The final results 
/** promise1 setTimeout1 setTimeout2 promise3 5 promise4 setTimeout3 setTimeout4 */

1.3 encounter async and await The situation of

Once encountered await Just let the thread go , Block subsequent code , Execute first async External sync code
After waiting , about await There are two situations : No promise object ; yes promise object

1, If not promise,await Will block the following code , Execute first async External sync code , After synchronization code execution , In return async Inside , hold promise Things that are , As await Result of expression
2, If it waits for one promise object ,await It will also be suspended. async Later code , Execute first async External sync code , Waiting for the Promise object fulfilled, And then put resolve As await The result of an expression .
3, If one Promise Passed to a await The operator ,await Will wait for Promise Normal processing completes and returns its processing results .

The following are the actual cases for reference only :

Case list :1 ( No, async await) The code is executed in sequence

function fn1() {
    
    return 1
}
function fn2 () {
    
    console.log(2)
    console.log(fn1())
    console.log(3)
}
fn2()
console.log(4)
//  result  2 1 3 4 

Case list :2( No, promise) If not promise,await Will block the following code , Execute first async External sync code , After synchronization code execution , In return async Inside , hold promise Things that are , As await Result of expression

async function fn1() {
    
    return 1
}
async function fn2 () {
    
    console.log(2)
    console.log(await fn1())
    console.log(3)
}
fn2()
console.log(4)
//  result  2 4 1 3

Case list :3( There is promise) If it waits for one promise object ,await It will also be suspended. async Later code , Execute first async External sync code , Waiting for the Promise object fulfilled, And then put resolve As await The result of an expression .

function fn1 () {
    
    return new Promise((reslove) => {
    
        reslove(1)
    })
}
async function fn2() {
    
    console.log(2)
    console.log(await fn1())
    console.log(3)
}
fn2()
console.log(4)

//  result  2 4 1 3

Case list : 4

async function async1() {
    
    console.log( 'async1 start' )
    await async2()
    console.log( 'async1 end' )
}
async function async2() {
    
    console.log( 'async2' )
}
async1()
console.log( 'script start' )
//  result : Execution results 
async1 start
async2
script start
async1 end

Once encountered await Just let the thread go , Block subsequent code
After waiting , about await There are two situations
No promise object
yes promise object
If not promise,await Will block the following code , Execute first async External sync code , After synchronization code execution , In return async Inside , hold promise Things that are , As await Result of expression
If it waits for one promise object ,await It will also be suspended. async Later code , Execute first async External sync code , Waiting for the Promise object fulfilled, And then put resolve As await The result of an expression .
If one Promise Passed to a await The operator ,await Will wait for Promise Normal processing completes and returns its processing results .
1.4 Based on the above cases, we probably know the execution sequence of asynchronous tasks .
Practice and try :

async function t1 () {
    
  console.log(1)
  console.log(2)
  await new Promise(resolve => {
    
    setTimeout(() => {
    
      console.log('t1p')
      resolve()
    }, 1000)
  })
  await console.log(3)
  console.log(4)
}

async function t2() {
    
  console.log(5)
  console.log(6)
  await Promise.resolve().then(() => console.log('t2p'))
  console.log(7)
  console.log(8)
}

t1()
t2()

console.log('end')

//  Output :
// 1
// 2
// 5
// 6
// end
// t2p
// 7
// 8
// undefined
// t1p
// 3
// 4
原网站

版权声明
本文为[SwJieJie]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202270542025617.html