JavaScript – What Are Deferred Callbacks?

jquerynode.js

I understand the idea of a callback, where I pass a function into another function and that function then uses the supplied function at will.

I am struggling to understand deferred callbacks, even after googling it.

Could someone provide a simple explanation please? I program in Ruby, but also know C/C++ a bit, but most of all I was a experienced assembly language programmer. So I am wondering is it a bit like a stack of callback addresses that get pop'd? I am hoping to learn jquery or node.js and these deferred callbacks seem integral to both. I understand basic threading principles (though mutex object makes my head hurt 😉

Best Answer

By request, here are comments presented as an answer:


I'm not sure you completely grok the fact that functions in JS are first-class objects, and can therefore be stored until needed, past the time they are created.

For example, say you want to write to a file, then print out a log message; so you call the "write()" function (or whatever) and pass it a function that outputs the log message (this is the deferred callback function). "write()" internally stores a reference to the given function, starts writing to the file, and sets up its own callback to know when the write is finished. It then returns before the write is done; when it is, the internal callback is somehow called (this is the underlying framework's job -- in the case of node.js, it's done with an event loop), which then calls your callback which prints the log message.

The "deferred" part simply means that your callback function isn't called right away; calling it is deferred until the appropriate time. In the case of asynchronous functions like many of those in node.js, the given callback is generally called when the operation completes (or an error occurs).

Most stuff is async in node.js, but in the browser with e.g. jQuery, most stuff is actually synchronous (except, obviously, for AJAX requests). Since first-class functions are so handy in JavaScript (especially because of great closure support), callbacks are used everywhere in the browser too, but they're not "deferred" for synchronous operations (except insofar as they're not called immediately by you, but later on by the function you call).

The fact that the underlying system is event-driven is orthogonal to the use of deferred callbacks; you can imagine a (very slow) version of node.js that started a thread for every operation, and then called your given callback when the thread finished its work, without using events at all. Of course, this is a horrible model, but it illustrates my point :-)