You can have the event handlers for "customevent1" and "customevent2" each signal a "Deferred" instance when they fire. You can use "$.when()" then to combine those two into one, and that's where you put the handler to fire only after both custom events have fired.
var df1 = $.Deferred(), df2 = $.Deferred();
$('whatever').bind('customevent1', function() {
// code code code
df1.resolve();
}).bind('customevent2', function() {
// code code code
df2.resolve();
});
var whenBoth = $.when(df1, df2);
whenBoth.then(function() {
// code to run after both "customevent1"
// and "customevent2" have fired
});
Old answer, here for completeness sake
You can make your own Deferred object that keeps track of the two conditions and fires "resolve" when both are set:
function watchEvents() {
var df = $.Deferred();
var flags = {};
$.each(Array.prototype.slice.call(arguments, 0), function() {
flags[this] = false;
});
var realResolve = df.resolve.bind(df);
df.resolve = function(eventName) {
flags[eventName] = true;
for (var ev in flags) if (flags[ev] === false) return;
realResolve();
};
return df;
}
Now you can call that function:
var df = watchEvents("customevent1", "customevent2");
And now your event handlers for those events just need to call "resolve" on that thing when they catch the events:
df.resolve(event.type);
Each handler reports its own type. Only when all of the event types requested when you called "watchEvents" have happened will the handler functions you register on "df" actually get called.
It occurs to me that another thing you could do would be to write a jQuery plugin that initializes a Deferred object for elements, and stores it in a ".data()" property. You could then write some more plugins that can be used by event handlers to signal themselves, and other plugins to register handlers for multi-event sequences. That'd be pretty cool, I think, but I need to spend some time pondering it.