将 JQuery Promise 数组转换为数组的 JQuery Promise 的最简洁方法是啥?
Posted
技术标签:
【中文标题】将 JQuery Promise 数组转换为数组的 JQuery Promise 的最简洁方法是啥?【英文标题】:What is cleanest way to turn Array of JQuery Promises into a JQuery Promise of an Array?将 JQuery Promise 数组转换为数组的 JQuery Promise 的最简洁方法是什么? 【发布时间】:2012-08-25 18:32:01 【问题描述】:我遇到了一个数组中有多个 JQuery Promise 的情况
var arrayOfPromises = [ $.Deferred(), $.Deferred(), $.Deferred(), $.Deferred() ]
并且需要把它变成一个数组的 JQuery Promise
var promiseOfArray = someTransform(arrayOfPromises)
在哪里
promiseOfArray.done(function(anArray)
alert(anArray.join(","));
);
使用文本创建警报
结果1,结果2,结果3,结果4
我目前在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
以达到相同的结果?
【问题讨论】:
Pass in an array of Deferreds to $.when()的可能重复 【参考方案1】:您可以只将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]
);
如果你真的只是想加入你所有延迟的字符串结果,我们可以使用一个小的数组黑客。 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);
);
;
【讨论】:
我认为 OP 实际上是在寻求一种“更短、更清洁”的方式,并且已经意识到.apply()
我会让问题更清楚,但我相信这将通过result1,result2,...
完成调用,但我希望使用[result1,result2,...]
的单个参数完成调用,请参阅jsfiddle.net/qk2mT/2“抛出对象 0 没有方法“加入”“
@Soldier.moth:done
处理程序没有得到结果数组;相反,它会传递 n 个参数,其中 n 是您最初传入的 Deferred 数量。使用隐式 arguments
对象循环遍历结果。
@josh3736:是的,我希望有一个很好的方法可以为我将arguments
转换为数组。可以通过定义 $.whenall
来完成,例如 function(arr) return $.when.apply($,arr).pipe(function() return [].slice.call(arguments,0); );
@Soldier.moth:是的,可以。我会使用Array.prototype.slice
而不是[]
,这样您就不会不必要地创建一个 Array 实例。查看更新。【参考方案2】:
当我们需要在多个 Promise 上调用它时,总是输入“丑陋”行 $.when.apply
也让我很困扰。但是Function.prototype.bind
救援!
var when = Function.prototype.apply.bind( jQuery.when, null );
现在,我们可以打电话了
when( someArrayWithPromises ).done(function()
);
Function.prototype.bind
是 ES5 的一部分,并且可以在浏览器中广泛使用。如果您还需要支持非常旧的浏览器,则可以使用大量简单的 shims
【讨论】:
您必须小心bind
,因为它在older browsers 中不可用。以上是关于将 JQuery Promise 数组转换为数组的 JQuery Promise 的最简洁方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章