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?
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.
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().
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.
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.
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);
});
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With