18 months later, I just hit something similar. I have a refresh button, and I want the old content to fadeOut
and then the new content to fadeIn
. But I also need to get
the new content. The fadeOut
and the get
are asynchronous, but it would be a waste of time to run them serially.
What I do is really the same as the accepted answer, except in the form of a reusable function. Its primary virtue is that it is much shorter than the other suggestions here.
var parallel = function(actions, finished) {
finishedCount = 0;
var results = [];
$.each(actions, function(i, action) {
action(function(result) {
results[i] = result;
finishedCount++;
if (finishedCount == actions.length) {
finished(results);
}
});
});
};
You pass it an array of functions to run in parallel. Each function should accept another function to which it passes its result (if any). parallel
will supply that function.
You also pass it a function to be called when all the operations have completed. This will receive an array with all the results in. So my example was:
refreshButton.click(function() {
parallel([
function(f) {
contentDiv.fadeOut(f);
},
function(f) {
portlet.content(f);
},
],
function(results) {
contentDiv.children().remove();
contentDiv.append(results[1]);
contentDiv.fadeIn();
});
});
So when my refresh button is clicked, I launch jQuery's fadeOut
effect and also my own portlet.content
function (which does an async get
, builds a new bit of content and passes it on), and then when both are complete I remove the old content, append the result of the second function (which is in results[1]
) and fadeIn
the new content.
As fadeOut
doesn't pass anything to its completion function, results[0]
presumably contains undefined
, so I ignore it. But if you had three operations with useful results, they would each slot into the results
array, in the same order you passed the functions.