Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
282 views
in Technique[技术] by (71.8m points)

javascript - What is cleanest way to turn Array of JQuery Promises into a JQuery Promise of an Array?

I run into the situation where I have multiple JQuery Promises in an Array

var arrayOfPromises = [ $.Deferred(), $.Deferred(), $.Deferred(), $.Deferred() ]

and need to turn it into a JQuery Promise of an Array

var promiseOfArray = someTransform(arrayOfPromises)

where

promiseOfArray.done(function(anArray){
  alert(anArray.join(","));
});

creates an alert with text

result1,result2,result3,result4

I currently define someTransform in coffeescript as

someTransform = (arrayOfPromises) ->
  $.when(arrayOfPromises...).pipe (promises...) ->
    promises

which transforms to the following 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 of the result I'm looking for.

I was wondering if there is a better(shorter,cleaner) way to define someTransform to achieve the same result?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can just apply the array as the arguments to $.when.

var promiseOfArray = $.when.apply($, arrayOfPromises);

To make the usage of this clearer, I like adding a method to $:

$.whenall = function(arr) { return $.when.apply($, arr); };

Now you can do:

$.whenall([deferred1, deferred2, ...]).done(...);

Update: By default, the done handler gets each result passed as a separate argument; you don't get an array of results.

Since you need to handle an arbitrary number of Deferreds, you can use the special implicit arguments object to loop over the results.

$.whenall([d1, d2, ...]).done(function() {
    for (var i = 0; i < arguments.length; i++) {
        // do something with arguments[i]
    }
});

If you really just want to join the string result of all your Deferreds, we can employ a little array hackery. arguments is array-like, but is not an Array:

$.whenall([d1, d2, ...]).done(function() {
    alert(Array.prototype.join.call(arguments, ','));
});

If you want to return an array of results to your done callback, we can tweak whenall to do it:

$.whenall = function(arr) {
    return $.when.apply($, arr).pipe(function() {
        return Array.prototype.slice.call(arguments);
    });
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...