var tds = ["0", "1", "2", "3", "4", "5", "6"];
for (var i = 0; i < tds.length; i++) {
jQuery("#notification-bar").html('I am doing ' + tds[i]);
jQuery.ajax({
url: "/ajax_json_echo/",
type: "POST",
timeout: 10000,
data: tds[i],
success: function(response) {
},
error: function(x, t, m) {
}
});
} //end for
jQuery("#notification-bar").html("Done!");
/ajax_json_echo/可能需要 10 秒甚至更长时间来处理 TDS。
通知栏的预期结果为
我在做 0
我正在做 1
我正在做 2
。
做!
我得到的实际结果是:
做!
我想这是由 jquery ajax 的异步变量设置为 true 引起的。
如果设置为 false,浏览器将被冻结。当它恢复时,我只得到"完成!
浏览器运行JavaScript并在同一线程上进行页面渲染,因此当JS运行时不会发生重绘。这意味着您的整个 for 循环将完成,状态消息将设置为"完成!在页面更新之前。
在异步为真的情况下,所有 Ajax 请求最初都排队,消息设置为"完成!",然后异步处理响应。在异步设置为 false 的情况下,Ajax 请求一次完成一个,在响应进来之前没有进一步的操作。无论哪种方式,浏览器都永远没有机会显示"我正在做..."消息。
您可以使用 Ajax 完成(或成功(回调中触发每个后续调用,而不是使用循环:
var tds = ["0", "1", "2", "3", "4", "5", "6"];
function doNextAjax(i) {
if (i < tds.length) {
jQuery("#notification-bar").html('I am doing ' + tds[i]);
jQuery.ajax({
url: "/ajax_json_echo/",
type: "POST",
timeout: 10000,
data: tds[i],
success: function(response) {
},
error: function(x, t, m) {
},
complete: function() {
doNextAjax(i + 1);
}
});
} else {
jQuery("#notification-bar").html("Done!");
}
}
doNextAjax(0);
每次调用doNextAjax()
时,它都会更新状态消息并发出单个 Ajax 请求,仅此而已。当函数退出浏览器时,有机会重新呈现并实际显示该消息。然后,当触发完整回调时,它会为下一项再次调用函数。当没有剩余项目时,它会设置"完成!"消息。
请注意,使用完整的回调来触发下一个 Ajax 调用意味着即使特定请求失败,它也会继续运行。如果你想在出错时停止,你可以摆脱完整的处理程序并将doNextAjax(i+1)
移动到成功回调中。
这是您使用成功回调参数来ajax()
- 在 AJAX 请求完成时运行函数。
http://api.jquery.com/jQuery.ajax/
如果你可以使用HTML5元素,请使用<progress>
元素,这就是他在那里的原因。
增加每个 ajax 请求的成功回调中的进度条值。
var progress = document.getElementById('progress');
progress.max = tds.length;
...
success: function(){
progress.value++;
}
现场演示
这是解决方案,你应该看看 jQuery deffered 对象
$.when($.ajax("/page1.php"), $.ajax("/page2.php")).done(function(a1, a2){
/* a1 and a2 are arguments resolved for the
page1 and page2 ajax requests, respectively */
var jqXHR = a1[2]; /* arguments are [ "success", statusText, jqXHR ] */
if ( /Whip It/.test(jqXHR.responseText) ) {
alert("First page has 'Whip It' somewhere.");
}
});
http://api.jquery.com/jQuery.when/
你写的响应会发生。改变
jQuery("#notification-bar").html('I am doing ' + tds[i]);
jQuery("#notification-bar").html("Done!");
自
jQuery("#notification-bar").append('I am doing ' + tds[i]);
jQuery("#notification-bar").append("Done!");
你会看到结果。但是,行为不是你所期望的。For 循环将一个接一个地启动所有 AJAX 调用。如果只想在最后一个调用完成后启动下一个 AJAX 调用,则应使用 jQuery 延迟对象来管理此调用。
我在这里总结了一个例子 http://jsfiddle.net/DXYZw/2/
var tds = ["0", "1", "2", "3", "4", "5", "6"];
var sendRequest = function(ary, data) {
if (!ary.length) {
// no more calls to be made
jQuery("#notification-bar").append("Done!");
return;
}
jQuery("#notification-bar").append('I am doing ' + tds.length);
dfAJAX(ary)
.done(sendRequest)
.fail(function() {
alert("error");
});
}
var dfAJAX = function(ary) {
var dfd = new jQuery.Deferred();
var dataToSend = ary.pop();
jQuery.ajax({
url: "/ajax_json_echo/",
type: "POST",
timeout: 10000,
data: dataToSend
})
.done(function(data) {
dfd.resolve(ary, data);
})
.fail(function() {
dfd.reject();
})
return dfd.promise();
}
sendRequest(tds);