什么是将JQuery Promise数组转换为数组JQuery承诺的最简洁方法?
我遇到了一个arrays中有多个JQuery Promises的情况
var arrayOfPromises = [ $.Deferred(), $.Deferred(), $.Deferred(), $.Deferred() ]
并需要将其转换为数组的JQuery承诺
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; }); };
这是我正在寻找的结果的jsFiddle 。
我想知道是否有更好(更短,更清洁)的方法来定义someTransform
来实现相同的结果?
您可以将数组作为参数应用于$.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
来做到这一点 :
$.whenall = function(arr) { return $.when.apply($, arr).pipe(function() { return Array.prototype.slice.call(arguments); }); };
当我们需要在多个promises上调用它时,它总是打扰我总是键入“丑陋”行$.when.apply
。 但是Function.prototype.bind
用于救援!
var when = Function.prototype.apply.bind( jQuery.when, null );
现在,我们可以打电话
when( someArrayWithPromises ).done(function() { });
Function.prototype.bind
是ES5的一部分,可以跨浏览器广泛使用。 如果您需要支持非常古老的浏览器,还有大量的简易垫片可用