Deferreds, new in jQuery 1.5, decouple logic dependent on the outcome of a task from the task itself. They’re nothing new to the JavaScript scene; Mochikit and Dojo have implemented them for some time, but with Julian Aubourg’s AJAX rewrite landing in 1.5, deferreds in jQuery was the logical next step. With deferreds, multiple callbacks can be bound to a task’s outcome, and any of these callbacks can be bound even after the task is complete. The task in question may be asynchronous, but not necessarily.
What’s more, deferreds are now built-into $.ajax() so you’ll get them automatically. Handlers can now be bound like this:
// $.get, an ajax request, is asynchronous by default. var req = $.get('foo.htm') .success(function( response ){ // do something with the response }) .error(function(){ // do something if the request failed }); // this might execute before the $.get() above is complete doSomethingAwesome(); // something additional to execute upon success, which might, or might not, // have fired by now. With $.ajax deferreds built-in, it doesn't matter. req.success(function( response ){ // do something more with the response // this will fire when success normally fires, or fire immediately // if prior success callbacks have already fired });
We are no longer limited to one success, error, or complete handler anymore, and instead of simple callback functions, these hooks are now self-managed first-in, first-out callback queues.
As shown in the example above, callbacks may be attached even after the AJAX request – or any observable task – has completed. For code organization this is great; the days of long unwieldy callbacks may be over. It’s almost as if $.queue() meets pub/sub. (more…)