简体   繁体   中英

setTimeout inside for loop doesn't behave as expected

I am creating a function that when you press a button it pops up a random symbol one at a time with a delay inbetween and then changes to a readable word once all symbols load up. I can't get the delay to work. I havent added the part that will turn the symbols into a readable word yet because I cant finish this.

//Brute Force
function work() {
    setTimeout(function() {
        var $rand = Math.ceil(Math.random() * 10);
        $('#txtBrute').append($sym[$rand]);
    },1000);
};
var i = 1;
var $sym = [1,9,"%","$",")",">","@","?","-","|",7];
$('#btnBrute').click(function() {
    var $pass = "password123";
    $('#txtBrute').html("");
    for(i = 1; i <= $pass.length; i++) {
        work();
    };
});

The issue is because you're calling work() in a loop, so all the timers execute immediately.

Instead of this you could make work() recursive. You can use the length of the password as a decremental value over each recursion. Try this:

 var timeout; var $sym = [1, 9, "%", "$", ")", ">", "@", "?", "-", "|", 7]; function work(length) { timeout = setTimeout(function() { var $rand = Math.ceil(Math.random() * 10); $('#txtBrute').append($sym[$rand]); --length != 0 && work(length); }, 1000); }; $('#btnBrute').click(function() { clearTimeout(timeout); var pass = "password123"; $('#txtBrute').html(""); work(pass.length); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button id="btnBrute">Go</button> <div id="txtBrute"></div> 

Also note that I added a clearTimeout() call, should someone decide to keep pressing the button while the recursive loop is still running.

setTimeout() doesn't affect when the rest of the code is run, so the loop launches all timeouts at once. As a result, they are all called at once, after 1000 milliseconds. Rory's answer suggests making work() recursive; another way to solve this, perhaps easier to implement but not as usable, would to pass a delay amount into work() :

 function work(delay) { setTimeout(function() { var $rand = Math.ceil(Math.random() * 10); $('#txtBrute').append($sym[$rand]); }, delay); }; var i = 1; var $sym = [1,9,"%","$",")",">","@","?","-","|",7]; $('#btnBrute').click(function() { var $pass = "password123"; $('#txtBrute').html(""); for(i = 1; i <= $pass.length; i++) { work(i * 1000); }; }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button id="btnBrute">Go</button> <pre id="txtBrute"></pre> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM