Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 844
Bobby Avatar asked Aug 30 '12 23:08

Bobby


People also ask

What is Promise method in jQuery?

promise() method returns a dynamically generated Promise that is resolved once all actions of a certain type bound to the collection, queued or not, have ended. By default, type is "fx" , which means the returned Promise is resolved when all animations of the selected elements have completed.

What is jQuery Deferred and Promise object?

A promise is, as the name says, a promise about a future value. Together with the Promise object , Deferred represents the jQuery implementation of promises. You can attach callbacks to it to get that value. It possesses a subset of the methods of the Deferred object : always(), done(), fail(), state(), and then().

Does jQuery get return a Promise?

jQuery objects can now return a Promise to observe when all animations on a collection have completed.” jQuery provides several methods that support custom animations (for example, the animate(), fadeIn(), and slideUp() methods). Their return value is the jQuery object.

What is Deferred function in jQuery?

Deferred() A factory function that returns a chainable utility object with methods to register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.


1 Answers

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);
    });
};
like image 166
josh3736 Avatar answered Oct 11 '22 17:10

josh3736