What are the differences between Deferred, Promise and Future in JavaScript? What are the differences between Deferred, Promise and Future in JavaScript? javascript javascript

What are the differences between Deferred, Promise and Future in JavaScript?


These answers, including the selected answer, are good for introducing promisesconceptually, but lacking in specifics of what exactly the differences are inthe terminology that arises when using libraries implementing them (and thereare important differences).

Since it is still an evolving spec, the answer currently comes from attempting to survey both references (like wikipedia) and implementations (like jQuery):

  • Deferred: Never described in popular references,1234but commonly used by implementations as the arbiter of promise resolution (implementing resolve and reject).567

    Sometimes deferreds are also promises (implementing then),56other times it's seen as more pure to have the Deferred onlycapable of resolution, and forcing the user to access the promise forusing then.7

  • Promise: The most all-encompasing word for the strategy under discussion.

    A proxy object storing the result of a target function whosesynchronicity we would like to abstract, plus exposing a then functionaccepting another target function and returning a new promise.2

    Example from CommonJS:

    > asyncComputeTheAnswerToEverything()    .then(addTwo)    .then(printResult);44

     

    Always described in popular references, although never specified as towhose responsibility resolution falls to.1234

    Always present in popular implementations, and never givenresolution abilites.567

  • Future: a seemingly deprecated term found in some popular references1and at least one popular implementation,8but seemingly being phased out of discussion in preference for the term'promise'3and not always mentioned in popular introductions to the topic.9

    However, at least one library uses the term generically for abstractingsynchronicity and error handling, while not providing then functionality.10It's unclear if avoiding the term 'promise' was intentional, but probably agood choice since promises are built around 'thenables.'2

References

  1. Wikipedia on Promises & Futures
  2. Promises/A+ spec
  3. DOM Standard on Promises
  4. DOM Standard Promises Spec WIP
  5. DOJO Toolkit Deferreds
  6. jQuery Deferreds
  7. Q
  8. FutureJS
  9. Functional Javascript section on Promises
  10. Futures in AngularJS Integration Testing

Misc potentially confusing things


In light of apparent dislike for how I've attempted to answer the OP's question. The literal answer is, a promise is something shared w/ other objects, while a deferred should be kept private. Primarily, a deferred (which generally extends Promise) can resolve itself, while a promise might not be able to do so.

If you're interested in the minutiae, then examine Promises/A+.


So far as I'm aware, the overarching purpose is to improve clarity and loosen coupling through a standardized interface. See suggested reading from @jfriend00:

Rather than directly passing callbacks to functions, something which can lead to tightly coupled interfaces, using promises allows one to separate concerns for code that is synchronous or asynchronous.

Personally, I've found deferred especially useful when dealing with e.g. templates that are populated by asynchronous requests, loading scripts that have networks of dependencies, and providing user feedback to form data in a non-blocking manner.

Indeed, compare the pure callback form of doing something after loading CodeMirror in JS mode asynchronously (apologies, I've not used jQuery in a while):

/* assume getScript has signature like: function (path, callback, context)    and listens to onload && onreadystatechange */$(function () {   getScript('path/to/CodeMirror', getJSMode);   // onreadystate is not reliable for callback args.   function getJSMode() {       getScript('path/to/CodeMirror/mode/javascript/javascript.js',            ourAwesomeScript);   };   function ourAwesomeScript() {       console.log("CodeMirror is awesome, but I'm too impatient.");   };});

To the promises formulated version (again, apologies, I'm not up to date on jQuery):

/* Assume getScript returns a promise object */$(function () {   $.when(       getScript('path/to/CodeMirror'),       getScript('path/to/CodeMirror/mode/javascript/javascript.js')   ).then(function () {       console.log("CodeMirror is awesome, but I'm too impatient.");   });});

Apologies for the semi-pseudo code, but I hope it makes the core idea somewhat clear. Basically, by returning a standardized promise, you can pass the promise around, thus allowing for more clear grouping.


What really made it all click for me was this presentation by Domenic Denicola.

In a github gist, he gave the description I like most, it's very concise:

The point of promises is to give us back functional composition and error bubbling in the async world.

In other word, promises are a way that lets us write asynchronous code that is almost as easy to write as if it was synchronous.

Consider this example, with promises:

getTweetsFor("domenic") // promise-returning async function    .then(function (tweets) {        var shortUrls = parseTweetsForUrls(tweets);        var mostRecentShortUrl = shortUrls[0];        return expandUrlUsingTwitterApi(mostRecentShortUrl); // promise-returning async function    })    .then(doHttpRequest) // promise-returning async function    .then(        function (responseBody) {            console.log("Most recent link text:", responseBody);        },        function (error) {            console.error("Error with the twitterverse:", error);        }    );

It works as if you were writing this synchronous code:

try {    var tweets = getTweetsFor("domenic"); // blocking    var shortUrls = parseTweetsForUrls(tweets);    var mostRecentShortUrl = shortUrls[0];    var responseBody = doHttpRequest(expandUrlUsingTwitterApi(mostRecentShortUrl)); // blocking x 2    console.log("Most recent link text:", responseBody);} catch (error) {    console.error("Error with the twitterverse: ", error);}

(If this still sounds complicated, watch that presentation!)

Regarding Deferred, it's a way to .resolve() or .reject() promises. In the Promises/B spec, it is called .defer(). In jQuery, it's $.Deferred().

Please note that, as far as I know, the Promise implementation in jQuery is broken (see that gist), at least as of jQuery 1.8.2.
It supposedly implements Promises/A thenables, but you don't get the correct error handling you should, in the sense that the whole "async try/catch" functionality won't work. Which is a pity, because having a "try/catch" with async code is utterly cool.

If you are going to use Promises (you should try them out with your own code!), use Kris Kowal's Q. The jQuery version is just some callback aggregator for writing cleaner jQuery code, but misses the point.

Regarding Future, I have no idea, I haven't seen that in any API.

Edit: Domenic Denicola's youtube talk on Promises from @Farm's comment below.

A quote from Michael Jackson (yes, Michael Jackson) from the video:

I want you to burn this phrase in your mind: A promise is an asynchronous value.

This is an excellent description: a promise is like a variable from the future - a first-class reference to something that, at some point, will exist (or happen).