What are the differences between Deferreds, Promises and Futures?
Is there a generally approved theory behind all these three?
These answers, including the selected answer, are good for introducing promises
conceptually, but lacking in specifics of what exactly the differences are in
the terminology that arises when using libraries implementing them (and there
are 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,
1
2
3
4
but commonly used by implementations as the arbiter of promise resolution (implementing resolve and reject).
5
6
7
Sometimes deferreds are also promises (implementing then),
5
6
other times it's seen as more pure to have the Deferred only
capable of resolution, and forcing the user to access the promise for
using then.
7
Promise: The most all-encompasing word for the strategy under discussion.
A proxy object storing the result of a target function whose
synchronicity we would like to abstract, plus exposing a then function
accepting 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 to
whose responsibility resolution falls to.
1
2
3
4
Always present in popular implementations, and never given
resolution abilites.
5
6
7
Future: a seemingly deprecated term found in some popular references
1
and at least one popular implementation,
8
but seemingly being phased out of discussion in preference for the term
'promise'
3
and not always mentioned in popular introductions to the topic.
9
However, at least one library uses the term generically for abstracting
synchronicity and error handling, while not providing then functionality.
10
It's unclear if avoiding the term 'promise' was intentional, but probably a
good choice since promises are built around 'thenables.'
2
References
Wikipedia on Promises & Futures
Promises/A+ spec
DOM Standard on Promises
DOM Standard Promises Spec WIP
DOJO Toolkit Deferreds
jQuery Deferreds
Q
FutureJS
Functional Javascript section on Promises
Futures in AngularJS Integration Testing
Misc potentially confusing things
Difference between Promises/A and Promises/A+
(TL;DR, Promises/A+ mostly resolves ambiguities in Promises/A)
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).
A Promise represents a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers to an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of the final value, the asynchronous method returns a promise of having a value at some point in the future.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
The deferred.promise() method allows an asynchronous function to prevent other code from interfering with the progress or status of its internal request. The Promise exposes only the Deferred methods needed to attach additional handlers or determine the state (then, done, fail, always, pipe, progress, state and promise), but not ones that change the state (resolve, reject, notify, resolveWith, rejectWith, and notifyWith).
If target is provided, deferred.promise() will attach the methods onto it and then return this object rather than create a new one. This can be useful to attach the Promise behavior to an object that already exists.
If you are creating a Deferred, keep a reference to the Deferred so that it can be resolved or rejected at some point. Return only the Promise object via deferred.promise() so other code can register callbacks or inspect the current state.
Simply we can say that a Promise represents a value that is not yet known where as a Deferred represents work that is not yet finished.
A promise represents a value that is not yet known
A deferred represents work that is not yet finished
A promise is a placeholder for a result which is initially unknown while a deferred represents the computation that results in the value.
Reference
http://blog.mediumequalsmessage.com/promise-deferred-objects-in-javascript-pt1-theory-and-semantics
Related
If we know that a Promise is definitely resolved, how can we access the value and if we can't, why not?
let a = Promise.resolve(123);
console.log(a.value); // ???
The following does not work- it prints "First, Last, 123"
console.log("First");
Promise.resolve(123).then(console.log);
console.log("Last");
I'm asking how to get the value of an already resolved Promise synchronously and if that's not possible, why not?
No, it is not possible to do this. This is by design.
The Promise A+ specification is meant to be used as a simple, consistent way to deal with asynchronous operations. One of the constraints is that passing a new callback on to then() on an already resolved promise will always execute on a later tick in the event loop, so things are consistent.
Adding a secondary way to inspect promise results would not have been impossible. It would probably have been quite easy to do so, but there's at least 2 problems with adding this to the specification:
If you're looking to build a specification, you want it to be as simple as possible. The specification itself actually only defines the then() function.
By adding this feature, you're opening the door to hordes of developers getting even more confused about something that's already hard to grok.
Promises and asynchronous operations are hard for people to understand. I see questions here daily about promises and not 'getting' it. If non-async way to access promise results would be added to the default promise, I'd imagine that this would be an even larger amount. It's good to try and enforce 'the right way' of doing things.
However, this decision is not simply made for you. You're not stuck there. You can very easily build your own version of a promise that has this feature, and still works with existing promises. As long as your object has a then() function that behaves according to Promises/A+ you can do with the rest of the object whatever you want.
Promises are always asynchronous in JS.
If you're confident that promise is going to resolve then you can access it with .then method.
a.then(function(value) {
console.log("First");
console.log(value);
console.log("Last");
// expected output: 123
});
Variable a will lookalike below if it is console.log
Promise {<resolved>: 123}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: 123
For error handling, you can error block as mentioned in MDN docs.
Promise.resolve(123).then(function(value) {
console.log(value);
}
Take a look on this
I am checking out the "Promises/A+" Specification, but could not understand the following things:
On Section 1. Terminology,
1.1. "promise” is an object or function with a then method whose behavior conforms to this specification.
1.2. “thenable” is an object or function that defines a then method.
So What is the difference between the terms "thenable" and "promise"?
Also in Section 2.3. The Promise Resolution Procedure,
The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as [[Resolve]](promise, x).
So my question is:
Why is it denoted within 2 opening and closing brackets? Is there any convention?
Thank you very much.
So What is the difference between the terms "thenable" and "promise"?
I think the section you've already cited does answer this very well:
A thenable is an object with a then method. Any object.
A promise is an object with a then method (i.e. a thenable) that conforms to the specification.
So far so simple. I think your actual question is: "Why are they distinguished?"
The problem is that by looking at an object you cannot decide whether it is a promise.
You might be able to tell that it is a promise because you can see that its then method is implemented by yourself or someone you trust - the promise library of your choice usually. You would be able to "see" that because the object does inherit from your promise prototype, or you can even compare the method being (referentially) identical to the function you've defined. Or any other inspection method that is sufficient for you.
You might be able to tell that it is not a promise because it has no then method.
But what do you do with an object that implements then, but is not known to be a promise? It's a thenable, and will be handled as such.
The Promises/A+ specification aims for interoperability between promise implementations, and uses the existence of a .then() method for duck typing. It does specify an exact algorithm on how to treat such thenables (that might be promises or at least have similar behaviour) so that you can create an actual, trusted ("known") promise from them.
Why is it denoted within 2 opening and closing brackets? Is there any convention?
Yes, the ECMAScript specifications use this syntax for internal methods and properties:
The names of internal properties are enclosed in double square brackets [[ ]].
Those properties do not actually need to exist, they're purely used to describe what should happen - an implementation must act as if it used them. They are totally abstract operations though.
This is a smart attempt to make it easier for promises to be interoperable between different libraries.
The spec uses the term thenable in just a few places. This one is the most important (empasis mine):
The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as [[Resolve]](promise, x). If x is a thenable, it attempts to make promise adopt the state of x, under the assumption that x behaves at least somewhat like a promise. Otherwise, it fulfills promise with the value x.
This will make implementors do a check like:
if (typeof(x.then) === 'function') {
// adopt the state of x
} else {
// fulfill promise with value x
}
If the spec instead said "if x is a promise, then...", how would the implementor know whether x is a promise or not? There's no practical way to make sure if x complies with the Promise spec just by inspecting it.
An implementor (say, library FooPromises might do something like
if (x instanceof FooPromises.Promise) {
// adopt the state of x
} else {
// fulfill promise with value x
}
and it would effectively reject any promises coming from different implementations.
Instead, by using a super-simple definition of thenable in this condition that implementors can easily verify, it's trivial to make this check and you make it possible for implementations to play nice with each other.
For you second question, I'm not sure but my idea would be that a notation [[Resolve]](promise, x) emphasises that it's an abstract operation. If they dropped the brackets and just said Resolve(promise, x), it would somehow imply that implementors should make a real function named Resolve and expose it.
This is not needed - Resolve is not part of the promises' interface; it's just a part of their behaviour that was important enough that it was given a name and a separate section in the docs.
I played with promises a few times a few years ago using either jQuery or Q. I'm now quite rusty and want to learn and use the new native ES6 promises.
I seem to remember one neat concept where you can "wait" on something and not care whether it's a plain object or a promise. If it's a promise the callback is called when it asynchronously completes, if it's anything else the callback is called immediately - maybe the next tick.
But I can't recall how this is done. I'm not sure if it has a name so it's proving difficult to Google for. I'm not sure if it's a standard feature across all JS promise implementations, or if it was just something only jQuery had.
What is this called? Can I still do this with native promises? Where can I read up on it?
Both jQuery's $.when() and ES6's Promise.all() exhibit the behaviour you refer to. Provide a promise and the function waits for the promise to resolve, but for any other value it returns immediately.
What do you call a function which returns a promise?
This is not the start of a joke
In the javascript community I've seen a function that returns a promise called being "thenable" enough times that I think "thenable" when I'm coding. It's a thenable function.
I like this name for a number of reasons:
1) Thenable describes the functional behaviour. If it returns a promise, you can call "then" on it.
2) It's unique. Promises aren't exactly monadic, so monad isn't appropriate. "Async" is more of a super class of functions and doesn't help describe the nature of a Promise. But "thenable" is uniquely Promisely.
3) I also like that it's not repeating Promise everywhere, (Promissory, Promisified, Promise Function, etc.) which is approaching a circular definition IMO. Being able to google one word which has one specific meaning is really nice.
Well...
The current answers aren't really correct. The truth of the matter is there is no short clever name for "function that returns a promise" that is in the consensus of the JS community.
In JavaScript
The spec doesn't name them in a special way, no documentation of any popular library names them in a special way. The promises specification does not name them in any special way.
The origin of promises
From the other hand, if we check the literature branch originating from Liskov and Shrira, they don't, and neither do Bogle nor Zondervan use any term other than "getting a promise" or "getting the future" for it (they do use claim for extracting the value).
If we check Mark Miller's work he does not use any terms for it either.
Other languages
In other languages things don't fare better. C# has no special name for methods that return Tasks (its promises). It does have "async functions" for functions that return async/await but that's only a strict subset. No special name in Scala, no special name in Python, no special name in Java and so on. The only thing close was parse's Android API naming their promises' then callbacks Continuation but that's hardly meaningful in this context.
Name suggestions
If it makes you feel any better - we don't have a name for something that returns an array either.
"Monadic functions" - Lots of functions can return monads that are not promises, moreover promises aren't really monads - they don't actually conform in their current form to monad laws nor does then make a valid bind. More importantly, very few JS developers even know what monads are and even fewer care.
"async function" - this might hold when (and if! it's not 100% sure now) the async modifier is added to the language. Right now and probably event then a lot of people consider things like setTimeout or fs.openFile to be async functions.
"Kleisli Arrows" - I took a type theory course and it covered this topic and I don't think me or any other students would call a function that returns a monad a Kleisli arrow. For one thing because it's an Arrow (yes yes, arrows are functions I get it).
Conclusion
To conclude, the people who invented promises, the people who specified them for JavaScript, the people who put that spec in writing, the spec itself, the promise libraries, the libraries written with those and the average user don't have any special name for it.
I think we can stick to A function that returns a promise.
If it makes you feel any better - we don't name "functions that return an int" either :)
In my experience, there are no individual words to describe functions that return a particular type. They are generally called "a function that returns a <Type>".
For example:
foo() is a function that returns a String
bar() is a function that returns a Number
baz() is a function that returns a Promise
In this context, Promise is being used similar to how an interface would in a strongly typed language.
Another example of a generic type being used would be
fizz() is a function that returns a collection
That's not to say that there can't be a word with a definition of "a function that returns a Promise", but there's no commonly used jargon to describe this.
"deferred function" is sometimes used to describe a function that returns promises or promise-like objects (i.e. jQuery's Deferred Object).
Functions that return promises can also be described by other more general words (in much the same way that a square can be described as a rectangle, parallelogram, rhombus, or quadrilateral).
Promises are monads, so they can be described as "monadic".
Promises are asynchronous, so functions that utilize them can be described as asynchronous as well.
Personally, I'd go with "promissory functions", as "promissory" means:
conveying or implying a promise
and I like the idea that the return value of such a function is "conveying a promise".
We call them asynchronous functions. Even if the function does nothing asynchronous itself, it at least returns a promise - an asynchronous value.
You can shorten that to async function, although that term is also used for the ES7 syntactic notation async function that creates functions which return promises implicitly (whose code can use await).
If you want to think of the type of functions that return monads (which promises are), you can call them Kleisli arrows. But you did ask a [javascript] question, not a [type-theory] one, did you?
Technically, a promise is a monad. Hence, a function that returns a promise is a monadic function.
I am checking out the "Promises/A+" Specification, but could not understand the following things:
On Section 1. Terminology,
1.1. "promise” is an object or function with a then method whose behavior conforms to this specification.
1.2. “thenable” is an object or function that defines a then method.
So What is the difference between the terms "thenable" and "promise"?
Also in Section 2.3. The Promise Resolution Procedure,
The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as [[Resolve]](promise, x).
So my question is:
Why is it denoted within 2 opening and closing brackets? Is there any convention?
Thank you very much.
So What is the difference between the terms "thenable" and "promise"?
I think the section you've already cited does answer this very well:
A thenable is an object with a then method. Any object.
A promise is an object with a then method (i.e. a thenable) that conforms to the specification.
So far so simple. I think your actual question is: "Why are they distinguished?"
The problem is that by looking at an object you cannot decide whether it is a promise.
You might be able to tell that it is a promise because you can see that its then method is implemented by yourself or someone you trust - the promise library of your choice usually. You would be able to "see" that because the object does inherit from your promise prototype, or you can even compare the method being (referentially) identical to the function you've defined. Or any other inspection method that is sufficient for you.
You might be able to tell that it is not a promise because it has no then method.
But what do you do with an object that implements then, but is not known to be a promise? It's a thenable, and will be handled as such.
The Promises/A+ specification aims for interoperability between promise implementations, and uses the existence of a .then() method for duck typing. It does specify an exact algorithm on how to treat such thenables (that might be promises or at least have similar behaviour) so that you can create an actual, trusted ("known") promise from them.
Why is it denoted within 2 opening and closing brackets? Is there any convention?
Yes, the ECMAScript specifications use this syntax for internal methods and properties:
The names of internal properties are enclosed in double square brackets [[ ]].
Those properties do not actually need to exist, they're purely used to describe what should happen - an implementation must act as if it used them. They are totally abstract operations though.
This is a smart attempt to make it easier for promises to be interoperable between different libraries.
The spec uses the term thenable in just a few places. This one is the most important (empasis mine):
The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as [[Resolve]](promise, x). If x is a thenable, it attempts to make promise adopt the state of x, under the assumption that x behaves at least somewhat like a promise. Otherwise, it fulfills promise with the value x.
This will make implementors do a check like:
if (typeof(x.then) === 'function') {
// adopt the state of x
} else {
// fulfill promise with value x
}
If the spec instead said "if x is a promise, then...", how would the implementor know whether x is a promise or not? There's no practical way to make sure if x complies with the Promise spec just by inspecting it.
An implementor (say, library FooPromises might do something like
if (x instanceof FooPromises.Promise) {
// adopt the state of x
} else {
// fulfill promise with value x
}
and it would effectively reject any promises coming from different implementations.
Instead, by using a super-simple definition of thenable in this condition that implementors can easily verify, it's trivial to make this check and you make it possible for implementations to play nice with each other.
For you second question, I'm not sure but my idea would be that a notation [[Resolve]](promise, x) emphasises that it's an abstract operation. If they dropped the brackets and just said Resolve(promise, x), it would somehow imply that implementors should make a real function named Resolve and expose it.
This is not needed - Resolve is not part of the promises' interface; it's just a part of their behaviour that was important enough that it was given a name and a separate section in the docs.