The result of a function is different depending on when it is executed.
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
Copy the code
In the code above, console.log(I) prints six sixes instead of 0,1,2,3,4,5. Here is the call time, and here is the picture and the truth.
This code uses a setTimeout function, which specifies how many milliseconds later a function or piece of code should be executed. So we have the case where the code above prints six sixes.
You can think of it this way
- Because JS is single-threaded, single-threaded means that all tasks need to be queued, and only after the previous task has finished can the next task be executed.
- Synchronous task: the last thing is not done, continue to do the last thing, until the last thing is done, do the next thing – > JS is mostly synchronous programming.
- Asynchronous task: We plan to do something, but instead of doing it right now, we wait a certain amount of time, so we don’t wait for it to do it, we continue to do it.
So in thefor
loop
- Ascribed value
i
A value of 0 - And then say is I less than 6? If the conditions are met, the next loop is continued.
setTimeout()
The code will wait for a moment when it gets here, and then it will skip ahead and continuei++
- perform
i++
, I is assigned 1. - Continue to judge that I <6 is sufficient to enter the second cycle.
- .
- .
- .
- Until I ++, when I is 6, I is not less than 6.
- Jump out of the loop
- Executing the first loop
setTimeout()
/ / print outi
- Executing the second loop
setTimeout()
/ / print outi
- Performing the third loop
setTimeout()
/ / print outi
- Performing the fourth cycle
setTimeout()
/ / print outi
- Executing the fifth cycle
setTimeout()
/ / print outi
- Execute the sixth loop
setTimeout()
/ / print outi
- It can now be seen that due to
setTimeout()
The execution time of isfor
The statement is executed, so each time the printed result is6
Here we need to introduce the followingsetTimeout()
The setTimeout function is used to specify how many milliseconds after a function or piece of code will be executed
At this point, the code will put the function on the task queue, and only put the function on the JS engine thread when it is idle and the specified time has been reached.
Even if setTimeout() is 0, the main thread will not execute its specified callback until the current code (stack) completes.
But many counterparts, often have to cheat, to importune must make it print out 0,1,2,3,4,5, is right here, 😑 😑, no problem
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
Copy the code
The code above will print out 0,1,2,3,4,5.
: — — — — — — — — – :
understand
To put it simply, write the let inside the for loop, which simply creates a block-level scope for each I, copying six I’s.
The variable I is declared by let, and the current I is only valid for this loop, so each loop’s I is actually a new variable.
Although the cycle of each round I will declare, but the JS internal engine will remember the value of the previous cycle, then copy the value of an I, on the initialization of a variable (I) at the same time, ensure that the next round of cycle can be calculated on the basis of the previous cycle, each loop I actually is a new variable.
In this way, 0/1, 2, 3, 4, 5 are obtained successively in 6 cycles, and setTimeout() starts to execute after the for loop ends, printing 0, 1, 2, 3, 4, 5.
There are other ways to print 0,1,2,3,4,5 besides let and for
Use immediate execution functions
let i = 0 for(i = 0; i<6; i++){ ! function(i){ setTimeout(()=>{ console.log(i) },0) }(i) }Copy the code
You can also use the third argument of setTimeout
let i = 0
for(i = 0; i<6; i++){
setTimeout((i)=>{
console.log(i)
},0,i)
}
Copy the code
Use the const keyword
let i
for(i = 0; i<6; i++){
const x = i
setTimeout(()=>{
console.log(x)
})
}
Copy the code