Introduction:

  • SetTimeout Delays the execution of a callback for a period of time. With the clearTimeout () to terminate

  • SetInterval performs callbacks at intervals; Use clearInterval () to terminate

It has always been thought that setTimeout is the execution of code in a unit of time, setInterval is the repeated execution of code in a unit of time. After learning a little bit about EventLoops and queues, it became clear why the unit times in both Settings were not always right. They’re both the same thing about pushing code into a task queue (not a microtask queue) after unit time. The code is not executed until the JS main thread task executes to it.

let nowTime = new Date().getTime();
let count = 0; 
// Time-consuming task
for(let i=0; i<100000; i++){let a = i
};
setInterval(function(){
    count++;
    console.log("Time difference:".new Date().getTime()-(nowTime + count*1000),"毫秒")},1000)
Copy the code

A simple for loop has an error of 10ms +, more for more complex or mainline programs. There is a popular graph on the web that explains what I think is an even more exaggerated error, in some cases ignoring a particular timer……

As you can see in the figure above, setInterval adds a callback to the queue every 100 milliseconds. After 100 milliseconds, T1 is added. After 200 ms, T2 adds the callback to the queue, but T1 is still executing, so T2 waits for the main program to finish and t3 is added at 300 ms, but T1 has just finished and is about to execute T2. But there was a timer instance in the mainline program when T3 joined. So T3 is ignored.

So setInterval’s disadvantages are obvious:

  • When using setInterval, certain callbacks are ignored in certain cases
  • Multiple timers may be executed consecutively (as shown in the figure above, T2 is executed immediately after T1, instead of at intervals)

Let’s look at the classic problem with setTimeout and for loops

for (var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}
Copy the code

It turns out to be five 5’s, which is obviously not one 5 per second from the speed of printing, but all at once. What causes it? The variables declared by var in the for loop are all global objects. When the loop starts, I =0 is stored in memory. SetTimeout pushes the callback into the task queue after 1s, while the main program is still executing the for loop. But because I is a global object, assignment accesses the same memory address every time I changes. The I accessed when the task queue starts printing is also the variable I in this global object, and the value of I can only be 5, which is valid for the last time in the for loop. So the previous code is similar to printing 5 5s per second.

Personal note, take me to study the source code of these two in the update. Next time I will simulate setInterval with setTimeout