我正在使用 jQuery 的 .when()
来 wrap an array of promises以便在所有 promise 都已解决时我可以采取一些行动。
$.when.apply($, requests).done(function () {
console.log(arguments); //it is an array like object which can be looped
var total = 0;
$.each(arguments, function (i, data) {
console.log(data); //data is the value returned by each of the ajax requests
total += data[0]; //if the result of the ajax request is a int value then
});
console.log(total)
});
假设我想在每个单独的 promise 得到解决时收到通知,作为显示进度的一种方式。例如,如果 requests
有 50 个请求,其中 3 个已解决,我希望能够在 6% 处显示进度条。有没有办法使用 $.when
以便它可以在不修改内部 promise 及其进度事件的情况下返回总体进度?
最佳答案
$.when()
不会为您发送进度通知。在每个单独的 promise 上注册进度通知,或者您可以制作自己的 $.when()
版本,首先在每个 promise 上注册完成通知,然后调用 $.when( )
。
$.whenWithProgress = function(arrayOfPromises, progessCallback) {
var cntr = 0;
for (var i = 0; i < arrayOfPromises.length; i++) {
arrayOfPromises[i].done(function() {
progressCallback(++cntr, arrayOfPromises.length);
});
}
return jQuery.when.apply(jQuery, arrayOfPromises);
}
$.whenWithProgress(requests, function(cnt, total) {
console.log("promise " + cnt + " of " + total + " finished");
}).then(function() {
// done handler here
}, function() {
// err handler here
});
我一直在考虑这个问题,让我有点困扰的是你想要进度通知,jQuery promise 有一个进度机制,但我们没有使用它。这意味着进度通知不像它们应有的那样具有可扩展性。
不幸的是,因为 $.when()
返回一个 promise(不是延迟的)并且你不能在 promise 上使用 .notify()
来触发进度通知,上面的代码是最简单的方法。但是,为了使用 .progress
通知而不是自定义回调,可以这样做:
$.whenWithProgress = function(arrayOfPromises) {
var cntr = 0, defer = $.Deferred();
for (var i = 0; i < arrayOfPromises.length; i++) {
arrayOfPromises[i].done(function() {
defer.notify(++cntr, arrayOfPromises.length);
});
}
// It is kind of an anti-pattern to use our own deferred and
// then just resolve it when the promise is resolved
// But, we can only call .notify() on a defer so if we want to use that,
// we are forced to make our own deferred
jQuery.when.apply(jQuery, arrayOfPromises).done(function() {
defer.resolveWith(null, arguments);
});
return defer.promise();
}
$.whenWithProgress(requests).then(function() {
// done handler here
}, function() {
// err handler here
}, function(cnt, total) {
// progress handler here
console.log("promise " + cnt + " of " + total + " finished");
});
反对第二个实现的一个论点是, promise 标准的努力似乎正在远离以任何方式将进展与 promise 联系起来(进展将有一个单独的机制)。但是,它现在在 jQuery 中,并且可能会在很长一段时间内存在(jQuery 不严格遵守 promise 标准),所以选择哪种方式真的是您的选择。
关于javascript - Deferred 和/或 Promise 数组的 jQuery.when() 进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26066198/