Four solutions for using setTimeout in JS for loop

Four solutions for using setTimeout in JS for loop

Overview

Let's first take a brief look at the operating mechanism of the setTimeout delay. setTimeout will first put the callback function in the waiting queue, and after other main programs in the waiting area are executed, the callback function will be executed in chronological order. It's essentially a question of scope.

Therefore, if this is done, the desired output 1.2.3.4.5 will not be obtained, but 5 consecutive 6s will be output.

for (var i=1; i<=5; i++) {
    setTimeout( function timer() {
        console.log( i );
     }, i*1000 );
}

This is because setTimeout is executed asynchronously. Each time the for loop is executed, setTimeout is executed once, but the function inside is not executed. Instead, it is placed in the task queue and waits for execution. Only when the tasks on the main line are completed will the tasks in the task queue be executed. That is to say, it will wait until the for loop is completely finished before executing the fun function. However, when the for loop ends, the value of i has become 6. Therefore, although the timer runs for 5 seconds, the content on the console is still 6.

(Note: The for loop needs to last for a few microseconds or milliseconds from the beginning to the end. When the timer runs out of one second, the for loop has already been completed.)

Let's look at another case:

for (var i=1; i<=5; i++) {
    (function() {
        setTimeout( function timer() {
            console.log( i );
        }, i*1000 );
    })();
}

From the operating mechanism of setTimeout, we can know that all external main programs will be run first. Although a closure is formed in the for loop, fun does not find an actual parameter, so there is no actual difference from the first example, and 5 consecutive 6s are still output.

Solution 1: Closures

Using closures is a classic approach:

for (var i=1; i<=5; i++) {
    (function(j) {
        setTimeout( function timer() {
            console.log( j );
        }, j*1000 );
    })(i);
}

We can find that the expected result is consistent with the output of 1 to 5 in sequence. This is because the actual parameters have a strong dependence on i inside the timer.

Through the closure, the variable i resides in the memory. When j is output, the variable value i of the external function is referenced. The value of i is based on the loop, and the output inside has been determined when setTimeout is executed.

Solution 2: Split the structure

We can also put the definition and call of setTimeout into different parts:

function timer(i) {
    setTimeout( console.log( i ), i*1000 );
}
for (var i=1; i<=5;i++) {
    timer(i);
}

The output on the console is still 1 to 5 in sequence.

Solution 3: let

Here is another way to solve this problem using es6's let:

for (let i=1; i<=5; i++) {
    setTimeout( function timer() {
        console.log( i );
     }, i*1000 );
}

Compared with the first example, this example only changes var to let, but the console outputs 1 to 5 in sequence.

Because the let at the head of the for loop not only binds i to the for loop, it actually rebinds it to each iteration of the loop body, ensuring that the value at the end of the previous iteration is reassigned. The function() in setTimeout belongs to a new scope. Variables defined by var cannot be passed into the execution scope of this function. By using let to declare block variables, they can act on this block, so function can use the variable i. The parameter scope of this anonymous function is different from the scope of the for parameter, and this is achieved by taking advantage of this. The scope of this anonymous function is somewhat similar to the attributes of a class and can be used by inner methods.

Solution 4: setTimeout third parameter

for (let i=1; i<=5; i++) {
    setTimeout( function timer() {
        console.log( i );
     }, i*1000, i );
}

Since the parameters passed in each time are values ​​taken from the for loop, 1 to 5 will be output in sequence.

The above are the details of the four solutions for using setTimeout in JS for loops. For more information about using setTimeout in JS, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • JavaScript uses setTimeout to achieve countdown effect
  • What are the basic uses of JavaScript setTimeout()
  • JavaScript setInterval() vs setTimeout() Timers
  • Simply use settimeout to see the operating mechanism of javascript
  • How to understand the JS operation mechanism through setTimeout
  • Look at the js function execution process from setTimeout
  • js learn to use setTimeout to implement round-robin animation
  • Analysis of JavaScript timer usage [setTimeout and clearTimeout]
  • Detailed explanation of the this pointing problem of timer setInterval and setTImeout in JS
  • Things about setTimeout in JavaScript

<<:  Detailed explanation of the use of shared memory in nginx

>>:  Detailed installation and use of RocketMQ in Docker

Recommend

How to set remote access permissions in MySQL 8.0

The previous article explained how to reset the M...

Learn the operating mechanism of jsBridge in one article

Table of contents js calling method Android 1.js ...

CSS to achieve single-select folding menu function

Don’t introduce a front-end UI framework unless i...

How to install mysql5.7.24 binary version on Centos 7 and how to solve it

MySQL binary installation method Download mysql h...

Ubuntu 20.04 Chinese input method installation steps

This article installs Google Input Method. In fac...

Introduction to Linux compression and decompression commands

Table of contents Common compression formats: gz ...

Detailed explanation of JS variable storage deep copy and shallow copy

Table of contents Variable type and storage space...

Problems and solutions for installing Docker on Alibaba Cloud

question When installing Docker using Alibaba Clo...

Lombok implementation JSR-269

Preface Introduction Lombok is a handy tool, just...

CSS to implement QQ browser functions

Code Knowledge Points 1. Combine fullpage.js to a...

CSS code to distinguish ie8/ie9/ie10/ie11 chrome firefox

Website compatibility debugging is really annoyin...

In-depth explanation of Session and Cookie in Tomcat

Preface HTTP is a stateless communication protoco...

How to reset MySQL root password under Windows

Today I found that WordPress could not connect to...