setTimeout with Loop in JavaScript

后端 未结 9 1580
挽巷
挽巷 2021-01-05 16:08

I have a very trivial question. For a simple loop with setTimeout, like this:

for (var count = 0; count < 3; count++) {
    setTimeout(function() {
               


        
相关标签:
9条回答
  • 2021-01-05 16:22

    Better solution IS "Forget both Loops and Recursion" in this case and use this combination of "setInterval" includes "setTimeOut"s:

        function iAsk(lvl){
            var i=0;
            var intr =setInterval(function(){ // start the loop 
                i++; // increment it
                if(i>lvl){ // check if the end round reached.
                    clearInterval(intr);
                    return;
                }
                setTimeout(function(){
                    $(".imag").prop("src",pPng); // do first bla bla bla after 50 millisecond
                },50);
                setTimeout(function(){
                     // do another bla bla bla after 100 millisecond.
                    seq[i-1]=(Math.ceil(Math.random()*4)).toString();
                    $("#hh").after('<br>'+i + ' : rand= '+(Math.ceil(Math.random()*4)).toString()+' > '+seq[i-1]);
                    $("#d"+seq[i-1]).prop("src",pGif);
                    var d =document.getElementById('aud');
                    d.play();                   
                },100);
                setTimeout(function(){
                    // keep adding bla bla bla till you done :)
                    $("#d"+seq[i-1]).prop("src",pPng);
                },900);
            },1000); // loop waiting time must be >= 900 (biggest timeOut for inside actions)
        }
    

    PS: Understand that the real behavior of (setTimeOut): they all will start in same time "the three bla bla bla will start counting down in the same moment" so make a different timeout to arrange the execution.

    PS 2: the example for timing loop, but for a reaction loops you can use events, promise async await ..

    0 讨论(0)
  • 2021-01-05 16:31

    This is to do with closure scoping. The same variable count is available in the scope for each of the setTimeout callback functions. You are incrementing its value and creating a function, but each instance of the function has the same variable count in its scope, and by the time the callback functions execute it will have the value 3.

    You need to create a copy of the variable (e.g. var localCount = count) inside a new scope in the for loop to make this work. As for doesn't create a scope (which is the cause of the whole thing) you need to introduce one with a function scope.

    e.g.

    for (var i = 0; i < 5; i++) {
      (function() {
        var j = i;
        setTimeout(function() {
          console.log(j)
        },
        j*100);
       })();
     }
    
    0 讨论(0)
  • 2021-01-05 16:31

    Think about it:

    1. The code executes a loop, in that loop it sets some code to run later.
    2. The loop finishes.
    3. The setTimeout code executes. What's the value of count going to be? The loop finished ages ago...
    0 讨论(0)
提交回复
热议问题