0

在加载了两到五个中等大小的数据文件之后,我经常需要在网页上加载一个函数。假设最多 3MB 的数据拆分为最多五个文件。

我尝试通过同时进行所有 AJAX 调用并在它们全部加载后加载 initialize() 函数来优化加载时间,如下所示:

var data1, data2;
$(document).ajaxStop(function() {
  $(this).unbind("ajaxStop"); //prevent running again when other calls finish
  initialize();
});

$.ajax({
    url: url_to_data_1,
    success: function (d) {
       data1 = d;
    }
});

$.ajax({
    url: url_to_data_2,
    success: function (d) {
       data2 = d;
    }
});

function initialize() { /* do something with data1 and data2 */ }

但是我厌倦了每次都粘贴这个,所以我想要一个这样的函数:

function multi_Ajax(urls, callback) {
    var data = {};

    //call init() after both the list of prayers and the word concordance index load
    $(document).ajaxStop(function() {
      $(this).unbind("ajaxStop"); //prevent running again when other calls finish
      callback(data);
    });

    for (var c = 0; c < urls.length; c += 1) {
        //data files
        $.ajax({
          url: urls[c],
          dataType: "json",
          success: function (d) {
            data[urls[c]] = d; console.log("Loaded " + urls[c]);
          }
        });
    }    
}

当然,这不起作用,因为 ajax 调用不存在供 ajaxStop 捕获。但我不明白 ajaxStop 是如何工作得足够好来进一步发展的。谢谢!

4

1 回答 1

1

我不确定为什么您的第二次尝试不起作用。根据文档,每当 ajax 请求完成时,jquery 将检查是否还有其他未完成的请求,如果没有则触发 ajaxStop。据我所知,循环调用$.ajax与对每个调用进行硬编码应该没有什么不同。

但是,正如 Barmar 在评论中所建议的那样,这$.when似乎是一种更清洁的方式来做你想做的事情。这是一个如何将数组(您可以在循环中填充)传递给的示例$.when将延迟数组传递给 $.when()

使用$.when似乎比$.ajaxStop因为如果有人后来出现并在您的循环之前或之后的某个地方添加了一个不相关的 ajax 请求,那将干扰 ajaxStop 触发的时间。$.when允许您明确说明要等待哪些 ajax 请求。

编辑:这是一个显示 ajaxStop 为循环发出的多个调用工作的小提琴:http: //jsfiddle.net/zYk5W/

看起来这对您不起作用的原因与 .ajax 或 .ajaxStop 无关;相反,这是您的成功回调中的范围问题。您的成功回调关闭c,但这c与外部(循环)范围使用的相同。当任何成功回调运行时,for 循环已完成并c已递增到urls.length. 因此,每次成功回调运行时,urls[c]都是未定义的。请参阅我链接的小提琴或循环内的 JavaScript 闭包——简单实用的示例,了解如何c在与循环的c.

于 2013-02-14T16:47:52.583 回答