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?