将 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 的最简洁方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

将 PHP 数组转换为 JQuery 数据

将 jQuery 数组字符串转换为 PHP 数组

使用 jQuery 将一个对象数组转换为另一个对象数组

如何将这个Promise对象转换成具有结果的数组

如何将数组json数据转换为jquery中的特定json?

如何将 HTML 表转换为 jQuery 键值对数组?