What Are the Differences Between Deferred, Promise and Future in JavaScript

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

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.

Js Deferred/Promise/Future compared to functional languages like Scala

Yes, and no.

While extremely similar. With JavaScript Promises that comply to the Promises/A+ spec .then is not really a monadic bind and does .map and .flatMap both. Inside a .then handler when you return a promise it will recursively unwrap it.

Promise.delay(1000).then(function() {
return Promise.delay(1000).then(function () {
return Promise.delay(2000);
}).then(function () {
return Promise.delay(5000)
});
}).then(function () {
alert("This is only shown after 8 seconds and not one");
});

(fiddle)

You are correct that the standard JS promise libraries and the A+ spec does not feature monadic promises. They have been discussed, and implementations like fantasy-promises exist. They follow a differnet spec and have little adoption. Also see this. There has been ongoing discussion about it in the language design discussion forum - esdiscuss and a monadic .chain method that does not flatmap and allows for monadic promises is considered but unlikely to make it.

This is for pragmatic reasons. The current way promises are implemented is immensely useful. Rare are the cases you actually want a Future[Future and normally you want continuations to just work in the language. Promises 'borrow' from monads and are 'monadic' in a sense themselves. .then is very close to bind and in my head I use them interchangeably :)

It is impossible to have a Promise[Promise[Value]] like a Future[Future[Value]] in Scala with most promise libraries. You'd have to wrap it in an object and have Promise[Container[Promise[Value]]].

Promise.delay(1000).then(function () {
return Promise.delay(1000).then(function () {
return {
wrap: Promise.delay(2000).then(function () {
return Promise.delay(5000);
})
};
});
}).then(function () {
alert("This logs after 1 second");
// I've also not seen a really solid use case
// except TypeScript type inference which is meh
});

(fiddle)

There are also a number of other smaller differences between the two, but generally you are correct in your assertions.

Difference between promise and deferred when wrapping your entire block of code in a promise?

A deferred is an object that has the resolve and reject method, allowing it's state to be changed. A promise doesn't.

As for generating promises in both ways, generally there shouldn't be any difference. I prefer the syntax of Promises since it wraps your logic in a function and avoids polluting the outer scope with variables, but that's about it.

Deferred versus promise

First: You cannot use $.Promise(); because it does not exist.

A deferred object is an object that can create a promise and change its state to resolved or rejected. Deferreds are typically used if you write your own function and want to provide a promise to the calling code. You are the producer of the value.

A promise is, as the name says, a promise about future value. You can attach callbacks to it to get that value. The promise was "given" to you and you are the receiver of the future value.

You cannot modify the state of the promise. Only the code that created the promise can change its state.

Examples:

1. (produce) You use deferred objects when you want to provide promise-support for your own functions. You compute a value and want to control when the promise is resolved.

function callMe() {
var d = new $.Deferred();
setTimeout(function() {
d.resolve('some_value_compute_asynchronously');
}, 1000);
return d.promise();
}

callMe().done(function(value) {
alert(value);
});

2. (forward) If you are calling a function which itself returns a promise, then you don't have to create your own deferred object. You can just return that promise. In this case, the function does not create value, but forwards it (kind of):

function fetchData() {
// do some configuration here and pass to `$.ajax`
return $.ajax({...});
}

fetchData().done(function(response) {
// ...
});

3. (receive) Sometimes you don't want to create or pass along promises/values, you want to use them directly, i.e. you are the receiver of some information:

$('#my_element').fadeOut().promise().done(function() {
// called when animation is finished
});

Of course, all these use cases can be mixed as well. Your function can be the receiver of value (from an Ajax call for example) and compute (produce) a different value based on that.


Related questions:

  • What are the differences between Deferred, Promise and Future in JavaScript?
  • What's the difference between a Deferred object and its own promise object?

What is the difference between future and promise in vertx?

Promise are for defining non-blocking operations, and it's future() method returns the Future associated with a promise, to get notified of the promise completion and retrieve its value. The Future interface is the result of an action that may, or may not, have occurred yet.

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

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.

Difference between Promise, Promise/A and Promise/A+

Is Promise a specification as well?

No. That's just a term with a context-dependent meaning. See for example What are the differences between Deferred, Promise and Future in JavaScript? or the Wikipedia entry on the topic for possible definitions.

Is Promise/A a specification as well?

Yes: http://wiki.commonjs.org/wiki/Promises/A

Why is it named A? Because there were other approaches as well.

I've read the Promise/A+ specification. What is the difference between them?

You must have missed https://promisesaplus.com/differences-from-promises-a.

What's the difference between a Future and a Promise?

According to this discussion, Promise has finally been called CompletableFuture for inclusion in Java 8, and its javadoc explains:

A Future that may be explicitly completed (setting its value and status), and may be used as a CompletionStage, supporting dependent functions and actions that trigger upon its completion.

An example is also given on the list:

f.then((s -> aStringFunction(s)).thenAsync(s -> ...);

Note that the final API is slightly different but allows similar asynchronous execution:

CompletableFuture<String> f = ...;
f.thenApply(this::modifyString).thenAccept(System.out::println);

Promise and Deferred?

Promise is a read only view of the deferred object, it does not allow to resolve/reject the deferred but just allows to register handlers to the respective events.

When a method creates a deferred, you want that method to have control on when it has to be marked as rejected/resolved, if you return the deferred from that method then anybody can call resolve/reject on that deferred object, instead jQuery provides a read only view of the deferred called promise which can be created by called deferred.promise() which can be returned from the method which created the deferred so other methods can only register handlers for fail/success/always events but cannot change the state of the deferred.

function create(){
var d = $.Deferred();
.....
//we can call resolve/reject using d
return d.promise();
}

var promise = create();
//we cannot call resolve/reject on this object
promise.done(function(){});


Related Topics



Leave a reply



Submit