我有一个带有多个AJAX请求的循环。每个Ajax都经常通过回调。每个Ajax都被推入承诺阵列。最后,$。始终使用时。
如果所有$.ajax
都取得了成功,则$.when.apply($, promises).always(...);
当所有$.ajax
呼叫成功时,都称为
但是例如,在3 $.ajax
呼叫第二个失败时,仅在第二个 $.when.apply($, promises).always(...);
之后发射,而不是所有3 $.ajax
呼叫suceed。
有帮助吗?遵循代码
$(".upload_all").bind("click", function() {
var confirmed_count = 0;
var error_count = 0;
var promises = [];
to_uploads.each(function(index,val) {
var elem = $(this);
var promise = $.ajax({
url: "/upload/storeUploadedFile",
type: 'POST',
}).always(function(data_or_jqXHR, textStatus, jqXHR_or_errorThrown) {
if (textStatus === "success") {
// ..
} else {
// ..
}
});
promises.push(promise);
});
$.when.apply($, promises)
.always(function() {
console.log("Promises Always! ") // do other stuff
});
}
作为 @kevin-b提到,如果拒绝传递给它的任何承诺,则拒绝$.when
返回(与Promise.all
几乎相同)的承诺将被拒绝。您可能希望这一点,通知用户一些上传的地方不成功。
但是$.ajax(..).always
(与promise.finally
相同)表示"在拒绝或解决此承诺时执行此回调"。当Ajax呼叫成功时,您可能想做一些事情,或者当其中任何一个失败时做其他事情。为此使用Promise.all(promises).then(...).catch(...)
。
$(".upload_all").bind("click", function() {
var confirmed_count = 0;
var error_count = 0;
var promises = to_uploads.map(function(index,val) { // using map instead of each here saves us a couple of steps
var elem = $(this);
return $.ajax({
url: "/upload/storeUploadedFile",
type: 'POST',
})
.then(function() { confirmed_count += 1; })
.catch(function() {
error_count += 1;
return Promise.reject(); // Return a rejected promise to avoid resolving the parent promise
});
});
// You can use the native API here which does not require doing the `apply` hack
Promise.all(promises)
.then(function() { alert('All uploads successful'); })
.catch(function() { alert(`Successful uploads: ${confirmed_count}. Failed uploads: ${error_count}`); }
}
记住jQuery使用了另一种诺言实现,但他们仍然对本机API做出响应:
-
.then
(jQuery味道中的.done
):附加一个可以在成功上运行的回调 -
.catch
(jQuery口味中的.fail
):附加一个回调要在错误时运行。除非返回拒绝的承诺,否则将解决承诺。 -
.finally
(jQuery味道中的.always
):尽管承诺被拒绝或解决,但在运行其他回调后将呼叫要运行。