花了一点时间试图实现这个并且有一个我觉得在firefox中工作得很好的解决方案,但是当在IE中测试发现使用async:false导致浏览器被锁定(停止响应并且显示已经冻结) )在通话期间。
要求基本如下。我提供了一系列用户可以查看的复选框。在特定时间,我调用我的函数“selectedSeriesData()'用于向我的服务发送请求一个接一个地获取请求的数据。我特别选择使用同步,这样我就可以在方法执行时向浏览器输出状态消息和警告。
例如。 "加载数据1/3",然后"加载数据2/3","加载数据3/3"
当然,我现在知道这会锁定某些浏览器,因此IE中的体验不仅会锁定浏览器,而且我试图显示的任何消息都不会显示。是否有任何类型的简单doEvents,例如我可以在每次ajax调用之后调用的操作,或者只是重构我的ajax调用的问题。如果是这样的话,根据我的要求提供任何实施建议吗?
以下是代码的简化摘要供参考。
function selectedSeriesData() {
var seriesData = [];
var index = 0;
$.each($("input[name='idCheckBox']:checked"), function () {
var id = $(this).val();
$("#loadingMessage").text("Loading " + id + "...");
$.ajax({
type: 'POST',
async: false,
url: '<%: loadSeriesDataPath %>',
dataType: 'json',
data: {
Id: id
},
success: function (data) {
seriesData[index] = data;
index++;
},
error: function (xhr, ajaxOptions, error) {
$("#warnings ul").append('<li>A communication error occured while attempting to load data for the series.</li>');
}
});
}
});
return seriesData;
}
答案 0 :(得分:1)
您可以使用jQuery Deferred objects继续使用异步请求,然后在所有结果完成后“加入”结果。
function selectedSeriesData(cb) {
var reqs = [];
$("#loadingMessage").text("Loading...");
$("input[name='idCheckBox']:checked").each(function () {
var id = $(this).val();
var req = $.ajax({
type: 'POST',
url: '<%: loadSeriesDataPath %>',
dataType: 'json',
data: {
Id: id
},
error: function(xhr, ajaxOptions, error) {
$("#warnings ul").append('<li>A communication error occured while attempting to load data for the series.</li>');
}
});
reqs.push(req);
});
$.when(reqs).done(function() {
cb($.makeArray(arguments));
});
}
现在您只需将回调传递给您的函数,然后只要所有结果都成功完成,它就会收到一个包含AJAX请求所有结果的数组。
注意:$.when
上的文档并不是很清楚它是否接受包含延迟的单个数组。如果它不起作用,请尝试$.when.apply($, reqs)
而不是$.when(reqs)
答案 1 :(得分:1)
我认为我问题的最佳答案是......你做错了。我没有按照建议的那样运气(也许是因为我理解它),所以我自己想出了以下答案。
基本上,使用回调来实现一种递归排队。对你们所有人来说这听起来很明显,但对我来说这是新手,我认为那里经验丰富的jqueryer会同意我的实施(如果我做得对,请告诉我!)
首先,不是循环访问我的复选框并发出ajax请求,而是建立一个请求数组。这样就不需要从原始方法返回我的结果,并开始一个方法执行链,从而导致所需的结果。
function selectedSeriesData() {
var requests = [];
$.each($("input[name='somethingCheckBox']:checked"), function () {
var id = $(this).attr('value');
var request = {
id: id
};
requests.push(request);
});
loadRequests(requests);
}
从请求数组中,启动调用loadRequests,初始化递归回调实现以从我的服务加载数据。
function loadRequests(requests)
{
$("#loader").show();
var seriesData = [];
loadRequestAt(requests, 0, seriesData);
}
调用的递归方法是loadRequestAt,它跟踪请求数组,加载此itteration的特定索引,以及调用方法时添加的seriesData。 Anon方法成功用于构建我的seriesData,Error用于报告错误,Complete用于开始下一次请求的迭代,或者如果已经完成所有请求,则将结果呈现给屏幕。
function loadRequestAt(requests, loadAtIndex, seriesData) {
var currentRequest = requests[loadAtIndex];
$("#loadingMessage").text("Loading " + currentRequest.id + "...");
$.ajax({
type: 'POST',
url: '<%: loadSeriesDataPath %>',
dataType: 'json',
data: {
Id: currentRequest.id
},
success: function(data) {
seriesData.push(data);
},
error: function(xhr, ajaxOptions, error) {
$("#warnings ul").append('<li>A communication error occured while attempting to load ' + currentRequest.id'.</li>');
},
complete: function() {
var nextIndex = loadAtIndex + 1;
if (nextIndex < requests.length) {
loadRequestAt(requests, nextIndex, seriesData);
} else {
$("#loader").hide();
renderResults(seriesData);
}
}
});
}
重要的经验教训。使用AJAX(异步JavaScript和XML)时,请使用异步调用。请使用提供的匿名回调方法来实现渐进式排队功能(我确定有一个可接受的名称,但我不确定)。希望我的学习步骤能帮助那些不熟悉jquery和ajax调用的人。谢谢!