我有一个网页,可以将无限数量的项目提交回服务器进行处理。
我决定使用AJAX调用将这些项目以25个为一组提交给Web服务。所以我的循环看起来像这样:
// Submit elements
for (var i = 0; i < ids.length; i += 25) {
var productIds = ids.slice(i, Math.min(i + 25, ids.length - 1));
$.post('/Services/ImportProducts.asmx/ImportProducts', JSON.stringify({ importProductIds: productIds }))
.done(function (result, statusText, jqxhr) {
// TODO: Update progress
})
.always(function () {
// TODO: Test for error handling here
});
}
到目前为止,这似乎是正确的。但是,当所有处理完成后,我想刷新页面。鉴于上面的代码,在最后一次AJAX调用完成时,我没有看到执行任务的简单方法。
由于$.post()
是异步的,因此该循环将在AJAX调用之前完成。由于AJAX调用可以按照与提交时不同的顺序完成,因此我无法简单地测试上次提交的调用何时完成。
我如何知道此代码何时完成?
答案 0 :(得分:6)
您可以使用jQuery&#39; s promises来完成此操作。一般工作流程涉及将每个promise添加到数组中,然后使用jQuery when应用该数组,以便在返回所有promise时执行另一个回调。
这样的事情应该有效:
var promises = []
for (var i = 0; i < ids.length; i += 25) {
var productIds = ids.slice(i, Math.min(i + 25, ids.length - 1));
var promise = $.post('/Services/ImportProducts.asmx/ImportProducts', JSON.stringify({ importProductIds: productIds }))
.done(function (result, statusText, jqxhr) {
// TODO: Update progress
})
.always(function () {
// TODO: Test for error handling here
});
promises.push(promise);
}
/*
Note, the "apply" function allows one to unwrap an array to parameters for a
function call. If you look at the jQuery.when signature, it expects to be
called like: $.when(promise1, promise2, promise3). Using .apply allows you
to satisfy the signature while using an array of objects instead.
See MDN for more information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
*/
$.when.apply($, promises)
.done(function() {
console.log("All done!") // do other stuff
}).fail(function() {
// something went wrong here, handle it
});
答案 1 :(得分:4)
你可以通过推送数组中的所有promises,然后使用$.when
来确定它们何时完成
var ajaxArr = [];
for (var i = 0; i < ids.length; i += 25) {
var productIds = {
importProductIds : ids.slice(i, Math.min(i + 25, ids.length - 1))
}
ajaxArr.push(
$.post('/Services/ImportProducts.asmx/ImportProducts', productIds, function(result, statusText, jqxhr) {
// TODO: Update progress
})
);
}
$.when.apply(undefined, ajaxArr).done(function() {
window.location.href = 'something'
});
答案 2 :(得分:2)
您可以设置一个计数,该计数等于您必须处理的循环数,然后从ajax请求返回时,递减计数器并检查它是否为零。当它达到零时,您可以刷新页面
var remains = ids.length;
// Submit elements
for (var i = 0; i < ids.length; i += 25) {
var productIds = ids.slice(i, Math.min(i + 25, ids.length - 1));
$.post('/Services/ImportProducts.asmx/ImportProducts', JSON.stringify({ importProductIds: productIds }))
.done(function (result, statusText, jqxhr) {
// TODO: Update progress
})
.always(function () {
// TODO: Test for error handling here
remains--;
if ( remains===0 ) {
// TODO: refresh here
}
});
}
答案 3 :(得分:0)
只计算完成了多少次回调;虽然回调是异步的,但代码在一个线程中运行,因此它们将按顺序调用,您可以安全地假设count == 25
完成后。