The execution timing of the JS function

Why six sixes?

let i = 0
for(i = 0; i < 6; i++){
  setTimeout(() = >{
    console.log(i)
  }, 0)}Copy the code

The code above, console.log(I), prints 6, 6, 6, 6, 6, not 0, 1, 2, 3, 4, 5 as we habitually understand it. The reason is setTimeout(), which executes a function or a specified piece of code after a certain amount of time.

  1. Declare variables firsti, and assign a value of 0.
  2. forLoop: variableiThe initial value is 0, which satisfies the conditioni < 6Execute the loop statementsetTimeout(()=>{console.log(i)}, 0)That means output lateriThe value of the. Then performi++.iBecomes 1.
  3. i = 1, meet the conditionsi < 6Execute the loop statement and output it lateriThe value of the.
  4. i = 2, meet the conditionsi < 6Execute the loop statement and output it lateriThe value of the.
  5. i = 3, meet the conditionsi < 6Execute the loop statement and output it lateriThe value of the.
  6. i = 4, meet the conditionsi < 6Execute the loop statement and output it lateriThe value of the.
  7. i = 5, meet the conditionsi < 6Execute the loop statement and output it lateriThe value of the.
  8. i = 6, the condition is not meti < 6.Jump out of the loop.
  9. At this point, a total of six “output lateriThe value of “.
  10. nowiThe value of is already 6, and the final output is 6 6.

JavaScript has traditionally been single-threaded, called the main thread. A thread is a basic process, and each thread can only perform one task at a time. Each task is executed in order, and only when the first one is finished can the next one begin.

So single threading means that all tasks need to be queued, and in the example above, console.log(I) in setTimeout() is executed after the for loop is complete.

But with a few changes like the one below, the final output is 0, 1, 2, 3, 4, 5.

for(let i = 0; i < 6; i++){
  setTimeout(() = >{
    console.log(i)
  }, 0)}Copy the code

The only difference between these two pieces of code is that the second piece of code writes let inside the for loop, for(let I = 0; i < 6; I ++){loop body} this sentence between the parentheses, there is a hidden scope, before each execution of the loop body, JS engine will automatically declare and initialize I in the loop once.

After 6 cycles, we get the values of 0, 1, 2, 3, 4, 5 of the 6 different values of I. After waiting for the end of the for loop, we execute setTimeout(), which prints 0, 1, 2, 3, 4, 5.

Is there any other way to print 0, 1, 2, 3, 4, 5?

Use immediate execution functions

let i = 0
for(i = 0; i < 6; i++){
    !function(i){
        setTimeout(() = >{
            console.log(i)
        },0)
    }(i)
}
Copy the code

usesetTimeout()The third parameter of

let i = 0
for(i = 0; i < 6; i++){
  setTimeout((i) = >{
    console.log(i)
  }, 0, i)
}
Copy the code

useconstThe keyword

let i 
for(i = 0; i < 6; i++){
    const x = i
    setTimeout(() = >{
        console.log(x)
    })
}
Copy the code

To study the reference

It took me two months to understand let