for循环中的setTimeout不会按预期运行

时间:2016-12-15 17:32:22

标签: javascript jquery settimeout

我正在创建一个函数,当你按下一个按钮时,它会一次弹出一个随机符号,中间有一个延迟,然后在所有符号加载后变为可读的单词。我无法延迟工作。我还没有添加将符号变成可读单词的部分,因为我无法完成此操作。

//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();
    };
});

2 个答案:

答案 0 :(得分:3)

问题是因为您在循环中调用work(),因此所有计时器都会立即执行。

而不是这个,你可以递归work()。您可以使用密码长度作为每次递归的递减值。试试这个:

&#13;
&#13;
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);
});
&#13;
<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>
&#13;
&#13;
&#13;

另请注意,我添加了clearTimeout()来电,如果有人决定在递归循环仍在运行时继续按下按钮。

答案 1 :(得分:2)

setTimeout()不会影响其余代码的运行时间,因此循环会立即启动所有超时。结果,它们在1000毫秒后立即被调用。罗瑞的回答建议递归work();解决这个问题的另一种方法,也许更容易实现但不是可用,会将延迟量传递给work()

&#13;
&#13;
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);
    };
});
&#13;
<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>
&#13;
&#13;
&#13;