循环中创建的所有计时器(使用setTimeout)同时触发?

时间:2012-04-02 19:04:55

标签: javascript

有人可以解释为什么我不能在每次请求之间得到所需的延迟吗? 它们都在同一时间发生。

$(window).load(function(){
    $('a[href]').each(function(){
        var linkk = $(this)
        var linkkhref = linkk.attr('href');

        window.setTimeout(function(){ conectar('HEAD', linkkhref, resp) }, 2000)

        function conectar(metodo, endereco, resposta, corpo) {
            callback = function(xhr) { resposta(xhr) };
            GM_xmlhttpRequest({
                "method"  : metodo,
                "url"     : endereco,
                "onerror" : callback,
                "onload"  : callback,
                "headers" : {'Content-Type':'application/x-www-form-urlencoded'},
                "data"    : corpo
            });
        };

        function resp(responseDetails) {
            // my response code here
        };
    });
});

我知道我使用Greasemonkey特定功能,但问题是关于javascript 无需GM知识。 :)

3 个答案:

答案 0 :(得分:4)

循环立即运行,并延迟conectar函数的每次执行,延迟时间代码的执行时间为2000毫秒。

对于简单的情况,我会使用:

$('a[href]').each(function(idx){
    ...
    window.setTimeout(function(){ conectar('HEAD', linkkhref, resp) }, idx*2000)

答案 1 :(得分:3)

一次调用所有链接的setTimeout。如果你想在通话之间延迟,你需要做这样的事情:

 var delay = 2000;
 $('a[href]').each(function(){
    var linkk = $(this)
    var linkkhref = linkk.attr('href');

    window.setTimeout(function(){ conectar('HEAD', linkkhref, resp) }, delay);
    delay += 2000;
    ....

答案 2 :(得分:2)

就像上面所说的尤金一样,这是因为setTimeouts一下子发生了。由于你正在使用jQuery,你可以做的一件事是使用jQuery的Deferred对象按顺序运行所有调用:

$(function() {
  // dfd is our "master" deferred, which we will use to pipe the requests, one at a time
  var dfd = $.Deferred();
  // set the deferred to resolve in 2 seconds, which will start the pipeline
  window.setTimeout(dfd.resolve, 2000);

  $('a[href]').each(function() {
    var linkk = $(this);
    var href = linkk.attr('href');
    var req = conectar(...)
    // replace the master deferred object with one that pipes into the next request
    dfd = dfd.pipe(req);
  });

  dfd.done(function() { alert("All requests completed!") });
});

当然,如果你关心的是他们在X秒后开始执行,那么其他答案就可以了。此方法允许您有效地“链接”每个方法,以便下一个方法在上一个完成时立即启动,并允许您在完成所有这些操作后发出信号(使用dfd.done)。