OverviewLet'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: ClosuresUsing 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 structureWe 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: letHere 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 parameterfor (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:
|
<<: Detailed explanation of the use of shared memory in nginx
>>: Detailed installation and use of RocketMQ in Docker
Description of port availability detection when p...
MySQL5.6.40 installation process under CentOS7 64...
When using the idea development tool to debug cod...
Written in front There are two ways to upgrade My...
Table of contents Preface 1. Linux changes the yu...
This article describes how to install lamp-php7.0...
MySQL dynamically modify replication filters Let ...
This article mainly introduces the solution to th...
This article example shares the specific code of ...
1. On a networked machine, use the default centos...
MySQL advantage: Small size, fast speed, low tota...
Perfect solution to the scalable column problem o...
1. Basic grammar Copy code The code is as follows...
background A colleague is working on his security...
Image tag : <img> To insert an image into a ...