The execution sequence of macro tasks and micro tasks from a for loop to the task queue (attached to the Great God connection)

Solve the order of execution of setTimeout, Promise, Promise.then from the shallower to the deeper.

If you are already familiar with for loops, scopes , closures, etc., then please click ** here " directly to enter the focus**.

Let's start with a simple for loop start

for (var i = 1;i <= 5;i ++) {
    
    
  console.log(i)
}
//1,2,3,4,5

What if we modify the requirements to require output every second ? (French talk)

for (var i = 1;i <= 5;i ++) {
    
    
  setTimeout(function() {
    
    
    console.log(i)
  },i*1000)
}
//6,6,6,6,6

That's right, it outputs 6 every second , a total of five times (not 5, brother, although I thought it was 5 before)
So how to output the corresponding number every second?

1、ES 6 let

for(let i = 0;i<5;i++) {
    
    
  setTimeout(function timer(){
    
    
    console.log(i);
  }, i * 1000);
}

2. Self-tuning function

for(let i = 0;i<5;i++) {
    
    
  +function(i){
    
    
    setTimeout(function timer() {
    
    
      console.log(i)
    }, i * 1000);
  }(i);
}

3. The extended parameter of setTimeout (the third parameter)

for (var i=1; i<=5; i++) {
    
    
  setTimeout( function timer(i) {
    
    
    console.log(i);    
   }, i*1000,i );
}

Then look at Promise

new Promise(function (resolve) {
    
    
  console.log('promise1')
  resolve()
 }).then(function () {
    
    
  console.log('then1')
})
//promise1,then1

After executing the Promise, print promise1, and then leave the .then function, print then1 (so easy ———— Erhage)

Okay, it's a little more complicated now ( emphasis ).

new Promise(function (resolve) {
    
    
  console.log('promise1')
  resolve()
 }).then(function () {
    
    
  console.log('then1')
})
for (var i = 1;i <= 5;i ++) {
    
    
  setTimeout(function() {
    
    
    console.log(i)
  },i*1000)
  console.log(i)
}
//promise1,1,2,3,4,5
//then1
//6,6,6,6,6

Why should the printed comment be divided into three lines?

Because of the three queue tasks:

Queue one

Executing code -> into the task queue -> function into the Promise -> Printing promise1-> The Promise.then () is added to a queue for execution Promise.then -> into the for loop -> the setTimeout setTimeout added to the queue waiting to be executed - > Print 1, 2, 3, 4, 5

At this point, promise1,1,2,3,4,5,then1 has been printed. Now there are two queues, which one should I choose first? Because the timer in the for loop is executed after 1000ms, the Promise.then() function is executed first

Queue Two

Execute the Promise.then() function -> output then1

Currently the console outputs promise1,1,2,3,4,5, then1

Queue Three

Execute console.log(i) once after one second, and execute 5 times in total (please note that i has looped five times at this time, and the value of this execution is 6!!! )
Print 6,6,6,6 , 6

After the output is completed, the result is: promise1,1,2,3,4,5,then1,6,6,6,6,6

Now, let's sort it out. Why do the 1,2,3,4,5 below the for loop first execute instead of the .then function?
Because it involves task queue

The task queue can be divided into macro tasks and micro tasks. XHR callbacks, event callbacks (mouse and keyboard events), setImmediate, setTimeout, setInterval, indexedDB database operations and other I/O are all macro tasks, and process.nextTick, Promise.then, MutationObserver (html5 new features) are micro tasks.

Mission order : first in program order on execution down from (the current overall macro code that we can be considered a task), met the macro task put him added to the appropriate task queue until the completion of the first round of code execution; and Then execute the corresponding micro task.
For example, the above chestnut: the first time the macro task is executed, it outputs promise1,1,2,3,4,5, and then the micro task is executed to output then1, and then the second round of macro task is executed, the second round of micro task...

Tired, I don’t know if I have made it clear. If there is any problem, I must bring it up in time, even if it is a typo.

So far, the chestnut is basically over, but what if setTimeout is not delayed (0ms) or contains a new Promise inside?
So, here comes the point

My article here is simplified based on the article by the boss, and the link to the article by the boss is attached below.
Gangster through train?

Guess you like

Origin blog.csdn.net/DoLi_JIN/article/details/106126008