how to slow down a javascript loop

前端 未结 5 1106
执念已碎
执念已碎 2021-01-04 10:59

I would like a add a 1-2 second delay on each iteration of the following loop.




        
相关标签:
5条回答
  • 2021-01-04 11:32

    Modern JS Solution:

    function timeout(ms) {
        return new Promise(resolve => setTimeout(resolve, ms))
    }
    
    async function slowedCode() {
        console.log("Before Delay")
        await this.timeout(Math.random() * 2000 + 500) // Wait random amount of time between [0.5, 2.5] seconds
        console.log("After Delay")
    }
    
    async function slowedForLoop() {
        const data = ["1","2","3","4","5"]
        for (let d of data) {
            console.log(d)
            await this.timeout(Math.random() * 100 + 500)
        }    
    }
    

    The only draw back is you have to execute the delay from inside an async function.

    0 讨论(0)
  • 2021-01-04 11:36

    I encourage getting rid of the loop and using setTimeout:

        $('#start').click(function() {
            var i = 0, max = 20, delay = 2000, run;
            run = function(){
               srPerformGeocode("TD Tower, 55 King Street West, Toronto, ON, Canada, M5K 1A2");
               if(i++ < max){
                  setTimeout(run, delay);
               }
            }
            run();
            return false;
        });
    
    0 讨论(0)
  • 2021-01-04 11:38

    You can do it this way with setTimeout():

    $(document).ready(function() {
        $('#start').click(function() {
            //srPerformGeocode("TD Tower, 55 King Street West, Toronto, ON, Canada, M5K 1A2");      
            var x = 0;
    
            function go() {
                srPerformGeocode("TD Tower, 55 King Street West, Toronto, ON, Canada, M5K 1A2");
                if (x++ < 20) {
                    setTimeout(go, 2000);
                }
            }
            go();
    
            return false;
        });          
    }); 
    

    This does make me wonder why you're doing a geocode lookup on the exact same address 20 times in a row?

    0 讨论(0)
  • 2021-01-04 11:46

    I have a feeling you'd rather not to start next loop iteration until the geocode lookup is truly complete. So, the keyword there is "callback":

    instead of the for..., do the below. I know it may not be something you're used to, but please try to grasp it (it should work).

    var dogeo = function(callback)
    {
        srPerformGeocode("address", callback);
    };
    
    var counter = 0;
    
    var geoCallback = function()
    {
             counter++;
    
             if(counter < 20)
             {
                 dogeo(geoCallback);
             }
    
    };
    
    
    dogeo(geoCallback);
    
    
    
    function srPerformGeocode(address, callback){     
        if (geocoder){                
            geocoder.geocode({ 'address': address }, function (results, status) {    
    
    
               // this function is a callback of geocode()
    
                if (status == google.maps.GeocoderStatus.OK){                                                                                                                                                                           
                    $('#status').prepend("Success : " + address + "<br/>");
    
                }
                else{
                    $('#status').prepend("Failed : " + address + "<br/>");
    
                }
    
                callback(); // let the caller know this is done
            });
        }
    }
    
    0 讨论(0)
  • 2021-01-04 11:51

    You probably want to use a timer for this. If you would just put a delay loop in the code, the result would only be that the code takes longer to run, but the final result will show up all at once after the code has finished.

    You can use the setTimeout or setInterval methods. Example:

    function(){
    
    var instructions = [
    function() { /* do something */ },
    function() { /* do something */ },
    function() { /* do something */ },
    function() { /* do something */ }
    ];
    
    var index = 0;
    
    var handle = window.setInterval(function() {
    if (index < instructions.length) {
      instructions[index++]();
    } else {
      window.clearInterval(handle);
    }
    }, 10);
    
    }();
    
    0 讨论(0)
提交回复
热议问题