我遇到了在数组中有多个JQuery Promise的情况
var arrayOfPromises = [ $.Deferred(), $.Deferred(), $.Deferred(), $.Deferred() ]
并需要将其转换为数组的JQuery Promise
var promiseOfArray = someTransform(arrayOfPromises)
,其中
promiseOfArray.done(function(anArray){
alert(anArray.join(","));
});
创建带文字的提醒
RESULT1,结果2,result3,result4
我目前在coffeescript中将someTransform
定义为
someTransform = (arrayOfPromises) ->
$.when(arrayOfPromises...).pipe (promises...) ->
promises
转换为以下javascript
var someTransform,
__slice = [].slice;
someTransform = function(arrayOfPromises) {
return $.when.apply($, arrayOfPromises).pipe(function() {
var promises;
promises = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return promises;
});
};
Here is a jsFiddle我正在寻找的结果。
我想知道是否有更好(更短,更清晰)的方式来定义someTransform
以获得相同的结果?
答案 0 :(得分:33)
您可以apply将数组作为$.when
的参数。
var promiseOfArray = $.when.apply($, arrayOfPromises);
为了更清楚地使用这个,我喜欢在$
中添加一个方法:
$.whenall = function(arr) { return $.when.apply($, arr); };
现在你可以做到:
$.whenall([deferred1, deferred2, ...]).done(...);
更新:默认情况下,done
处理程序会将每个结果作为单独的参数传递;你没有得到一系列结果。
由于您需要处理任意数量的Deferred,您可以使用特殊的隐式arguments
对象来循环结果。
$.whenall([d1, d2, ...]).done(function() {
for (var i = 0; i < arguments.length; i++) {
// do something with arguments[i]
}
});
如果您真的只想加入所有Deferred的字符串结果,我们可以使用一个小阵列hackery。 arguments
类似于数组,但不是Array
:
$.whenall([d1, d2, ...]).done(function() {
alert(Array.prototype.join.call(arguments, ','));
});
如果您想将一系列结果返回给done
回调,我们可以调整whenall
to do it:
$.whenall = function(arr) {
return $.when.apply($, arr).pipe(function() {
return Array.prototype.slice.call(arguments);
});
};
答案 1 :(得分:6)
当我们需要在多个承诺上调用它时,它总是打扰我总是键入“丑陋”行$.when.apply
。但Function.prototype.bind
用于救援!
var when = Function.prototype.apply.bind( jQuery.when, null );
现在,我们可以致电
when( someArrayWithPromises ).done(function() {
});
Function.prototype.bind
是ES5的一部分,可以跨浏览器广泛使用。如果您需要支持非常古老的浏览器,还有大量简单的垫片