The execution time of a function is necessarily related to the execution environment

Single thread

The Javascript language executes in a “single thread” environment.

What is a single thread?

One task at a time. If more than one task exists, the number must be queued, and the n+1 task will be executed after the n task is completed.

advantages

  • Implementation is simple, just face the code is executed from top to bottom.
  • The execution environment is relatively simple.

disadvantages

  • As long as one task takes a long time to execute, subsequent tasks will have to wait.
  • Delay the execution of the whole procedure.

The solution

The Javascript language divides tasks into two modes of execution: Synchronous and Asynchronous.

synchronous

“Synchronization mode” is the mode of the previous section, the latter task waits for the end of the previous task, and then executes. The execution order of the program is consistent and synchronized with the order of the task.

asynchronous

“Asynchronous mode” is completely different, each task has one or more of the callback function (the callback), before the end of a task, not to perform a task, after but the callback function, after a task is before the end of a task before execution, so the program execution order the order is not consistent with the task, asynchronous.

Note: A function that is passed as an argument to another function and is called within that external function is called a callback function.

Execution time

When a function is executed, it has different effects.

Timing of synchronization

Go straight to the example 🌰

let  a = 1
function fn(){
    console.log(a)
}
fn()   / / 1
Copy the code

Obviously executing the code from top to bottom, everything is bland.

  1. Declare the variable a and assign it to 1
  2. Declare the function fn, which prints the value of a in the console
  3. Call the function fn()
  4. Output 1
let  a 
function fn(){
    console.log(a)
}
fn()   //undefined
a=2
Copy the code

Everything is under control because the assignment of a precedes the function call.

  1. Declare variable A
  2. Declare the function fn, which prints the value of a in the console
  3. Call the function fn()
  4. Output a / / undefined
  5. A is assigned 2

The above two examples can clearly see the timing characteristics of synchronous execution, sequential execution

Asynchronous execution timing

This must be an example of asynchrony that you’ve seen a million times 🌰, because it’s so classic that newcomers can’t see it right.

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

Output: 6 6 6 6 6 6 6 6

Why not 0, 1, 2, 3, 4, 5?

Obviously, it’s 0, 1, 2, 3, 4, 5. Why don’t we put an example of synchronization? 🧐

Take a look at how the code goes.

  1. Declare variable I
  2. I is assigned 0
  3. Criteria True if I <6
  4. Enter the loop, encounter setTimeout (timer),
  5. SetTimeout means that you need to print I on the console
  6. i++
  7. . Repeat steps 3, 4, 5, and 6
  8. When I =6, the loop ends
  9. SetTimeout starts to output the value 6 for I, repeating it six times

So setTiemout just prints the value of the last I

What about the 0 in setTimeout? SetTimeout (fn,0) means that fn is executed immediately after 0 seconds (actual minimum delay >=4ms) when the functions and statements of the synchronization task are finished. This delay only controls how long fn needs to wait to execute.

Just want to0, 1, 2, 3, 4, 5?

Use the block-level scope of let

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

Because variables declared with a let in a for statement are local variables that follow the block scope, each time the for loop executes, a separate scope is generated and a new I is generated, equivalent to six I’s. At this point, each time setTimeout() is executed, the corresponding I will be printed, and the result will be 0, 1, 2, 3, 4, 5.

Using a recursive

function showTime(count) {
  console.log("count is : ", count);
  if (count == 5) {
      console.log("All is Done!");
  } else {
      count ++;
      setTimeout(function() {
          showTime(count);
      }, 0);
  }
}

showTime(0)
// count is : 0
// count is : 1
// count is : 2
// count is : 3
// count is : 4
// count is : 5
Copy the code

Use self-executing functions

function test() {
  for (var i = 0; i < 6; ++i) {
      (function(i){
      setTimeout(function() {
          console.log("index is :", i);
      }, 1000)
      })(i)
  }
}
test();
//index is : 0
//index is : 1
//index is : 2
//index is : 3
//index is : 4
//index is : 5
Copy the code