3 回答
TA贡献1807条经验 获得超9个赞
更复杂的诺言库有一个allSettled()类似的功能Q或Promise.settle类似蓝鸟。
在jQuery中,您也可以自己实现这样的函数并$使用它扩展命名空间,但只有在经常需要它并进行性能优化时才需要这样做。
一个更简单的解决方案是为你正在等待的每一个创建一个新的承诺,并且即使当底层的一个被拒绝时也要实现它们。然后你可以$.when()毫无问题地使用它们。简而言之:
// using Underscore's .invoke() method:
$.when.apply(null, _.invoke(promises, "then", null, $.when)).done(…)
更稳定:
$.when.apply($, $.map(promises, function(p) {
return p.then(null, function() {
return $.Deferred().resolveWith(this, arguments);
});
})).then(…);
您可以then稍微更改回调以区分最终的已完成和已拒绝的结果done。
TA贡献1829条经验 获得超7个赞
铁匠铺,
首先让我们假设你的承诺是一个数组。
var promises = [....];
您似乎想要的是.when()应用于这些承诺的某些转换,这样任何被拒绝的承诺都会转换为已解决,同时对已经解决的承诺透明。
所需的操作可以非常简洁地写成如下:
$.when.apply(null, $.map(promises, resolvize)).done(...);
//or, if further filtering by .then() is required ...
$.when.apply(null, $.map(promises, resolvize)).then(...);
resolvize转换机制在哪里。
那应该resolvize()怎么样?让我们利用特征.then()来区分已解决和被拒绝的承诺,并做出相应的响应。
function resolvize(promise) {
//Note: null allows a resolved promise to pass straight through unmolested;
return promise.then(null, function() {
return $.Deferred().resolve.apply(null, arguments).promise();
});
}
未经测试
与resolvize在某些外部范围,它可以被提供给被用在$.when.apply($.map(promises, resolvize))任何需要它的表达。这很可能是足够的,没有达到用新方法扩展jQuery的程度。
无论转变如何实现,您最终都会遇到潜在的问题; 即知道.done()回调的每个参数,是否最初解决或拒绝其相应的承诺。这是您将拒绝转换为解决方案所付出的代价。但是,您可以从原始承诺被解决/拒绝的参数中检测原始状态。
添加回答
举报