我经常需要在加载了两到五个中等大小的数据文件之后在网页上加载一个函数。假设最多5个文件分割最多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]);
}
});
}
}
当然,这不起作用,因为ajaxStop不存在ajax调用。但我不明白ajaxStop如何运作得足够好以进一步发展。谢谢!
答案 0 :(得分:1)
我不确定为什么你的第二次尝试不起作用。根据文档,每当ajax请求完成时,jquery将检查是否还有其他尚未完成的请求,如果没有,则触发ajaxStop。在我看来,在循环中调用$.ajax
与硬编码每个调用不应该有任何不同。
然而,正如Barmar在评论中所说,$.when
似乎是一种更干净的方式来做你想做的事情。以下是如何将数组(可以在循环中填充)传递给$.when
的示例:Pass in an array of Deferreds to $.when()
使用$.when
似乎比$.ajaxStop
更清晰,因为如果有人后来出现并在循环之前或之后的某处添加了无关的ajax请求,那么会干扰ajaxStop触发的时间。 $.when
允许您明确说出您要等待哪些ajax请求。
编辑:这是一个小提示,显示ajaxStop正在为循环中发出的多个调用工作:http://jsfiddle.net/zYk5W/
看起来这不适合你的原因与.ajax或.ajaxStop无关;相反,它是成功回调中的范围问题。您的成功回调将关闭c
,但这与外(循环)范围使用的c
相同。当任何成功回调运行时,for循环已完成,c
已增加到urls.length
。因此,每次成功回调运行时,urls[c]
都是未定义的。请参阅我链接的小提琴或JavaScript closure inside loops – simple practical example,了解如何在与循环c
分开的范围内为每个成功回调自己的c
。