I’m trying to sync up multiple ajax callbacks using jQuery.Deferrd objects. Obviously jQuery.when handles this for you however my code is architected in such a way that the ajax requests aren’t called in the same method. So for example this is the flow:
// A Button is clicked
// Module 1 requests a snippet of html and updates the DOM
// Module 2 requests a different snippet of html and updates the DOM
I need both Modules to update the DOM at the same time meaning I need to ensure the callbacks are run after both requests have returned.
Module 1 and Module 2 need to be able to exist without each other and should have no knowledge of one another so the requests can’t be made together using $.when(doMod1Request(), doMod2Request()).then(function () { … }) and the callbacks should be independent too.
I’ve therefore written a wrapper around ajax which adds the callbacks to a deferred object and in a similar way to $.when resolves the deferred object once the ajax requests have returned the same number of times as the number of callbacks on the deferred object.
My dilemma is however deferred.resolve() can only be called with one set of arguments so each callback get’s the same value.
e.g.
var deferred = new $.Deferred();
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-1"></div>
});
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-1"></div>
});
deferred.resolve('<div class="html-snippet-1"></div>');
Whereas I’d want something like this:
var deferred = new $.Deferred();
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-1"></div>
});
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-2"></div>
});
deferred.resolve(['<div class="html-snippet-1"></div>', '<div class="html-snippet-2"></div>']);
Is this possible or am I going about this incorrectly?
I’d say this is perfectly valid. Assuming your independent modules, you would do (with two Promises):
Now, if you want to to execute the updates together and only if the two requests both succeeded, just write
This only gets ugly if you call your resolve functions with multiple arguments, as jQuery is a bit inconsistent there and does not really distinguish multiple arguments from one array argument.
To uncouple them with that publish-subscribe pattern you are using, I’d recommend the following: