Javascript 在循环中创建的所有计时器(使用setTimeout)是否同时启动?

Javascript 在循环中创建的所有计时器(使用setTimeout)是否同时启动?,javascript,Javascript,有人能解释为什么我不能在每个请求之间获得所需的延迟吗? 它们同时发生 $(window).load(function(){ $('a[href]').each(function(){ var linkk = $(this) var linkkhref = linkk.attr('href'); window.setTimeout(function(){ conectar('HEAD', linkkhref, resp) }, 2000)

有人能解释为什么我不能在每个请求之间获得所需的延迟吗?
它们同时发生

$(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知识。:)

因为一次调用所有链接的
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;
    ....

循环立即运行,并将
conectar
函数的每次执行延迟2000毫秒,从执行代码开始计算

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

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

正如Eugene所说,这是因为设置超时同时发生。因为您使用的是jQuery,所以可以使用jQuery的对象按顺序运行所有调用:

$(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
)。

所有答案都非常有效。我把它选对了,因为它没有改变我的代码——只是添加了
idx