【问题标题】:behavior of ajax call inside a for loopfor循环内ajax调用的行为
【发布时间】:2014-04-03 09:18:01
【问题描述】:
  for (var i in arr) {
    console.log(i);
    $.get(searchURL, function (result) {
      console.log(result);
    }); // end of inner async request
  } // end of outer arr

在这种情况下,我看到了

1
2
3
result
result
result

但我的意图和期望是

1
result
2
result
3 
result

我认为发生这种情况是因为每个 ajax 调用所花费的时间都比整个 for 循环的执行时间长。这是正确的吗?如果是这样,这样做的传统方法是什么?

更新:

我发现使用 jQuery 的 $.each 函数而不是 for loop 给了我预期的输出。 $.each 函数是否旨在与循环内的异步调用一起使用?

【问题讨论】:

  • .each() 在运行 ajax 调用时不会改变。它将使您能够在每个完成函数中唯一地访问 i 变量,但您的代码示例和问题并没有说明这一点。

标签: javascript jquery ajax


【解决方案1】:

它启动所有三个异步 ajax 调用,然后一个接一个地从它们返回结果。因为它们是异步的,所以在当前 javascript 线程完成并返回事件队列以开始为到达的 ajax 结果提供服务之前,不会处理任何结果。您看到的结果仅与 ajax 调用是异步的这一事实有关,与它们返回结果所需的时间无关。

如果您想连续运行它们,那么您可以构建代码以在 ajax 调用上调用,然后在完成后调用下一个 ajax 调用,依此类推:

function doAjax(arr) {
    var i = 0;

    function next() {
        if (i < arr.length) {
            console.log(i);
            // do something with arr[i] here
            $.get(searchURL, function (result) {
                 console.log(result);
                 i++;
                 next();
            }); // end of inner async request
        }
    }
    next();
}

【讨论】:

    【解决方案2】:

    ajax 调用是异步的,JS 是单线程的。这意味着无论服务器响应多快,for 循环始终会首先完成。尝试将 i 传递给您的回调。

    var responseHandle= function (i,result) {
          console.log(i, result);
        };
    
    for (var i in arr {
        console.log(i);
        $.get(searchURL, responseHandle.bind(null,i));
    } 
    

    【讨论】:

    • 这仍然会记录 1,2,3 然后结果就像 OP 的问题一样。它将使i 在响应函数中可用,但我认为这不是 OP 的问题。
    【解决方案3】:

    $.get 是异步的。如果您使用的是 jQuery async: false:

    $.ajax({
        type:'get',
        url: searchURL,
        async: false,
        complete: function(response){
            //done
        }
    });
    

    否则你可以使用jQuery's Deffered。

    【讨论】:

    • async false 是一个可怕的建议。在所有 ajax 调用期间锁定浏览器。
    • @jfriend00 感谢您的信息。我不知道它会锁定浏览器,我只是知道这个选项。我检查了docs 并看到“请注意,同步请求可能会暂时锁定浏览器,在请求处于活动状态时禁用任何操作。”所以不用说我不会再推荐这个选项了。
    猜你喜欢
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 2017-02-25
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多