Difference between defer().promise and Promise
Well, this is about the promise resolution source. Q and a bunch of other libraries offer two APIs:
- The legacy
defer
API - in which you create a deferred that you can.resolve(value)
and it has a promise you can return. - The promise constructor - which is the modern API in which you create the promise from a completion source.
Roughly doing:
var d = Q.defer();
setTimeout(function(){ d.resolve(); }, 1000);
return d.promise;
Is the same as:
return new Promise(function(resolve, reject){
setTimeout(resolve, 1000);
});
so you might be asking
Why do we need two APIs?
Well, the defer API came first. It's how some other languages deal with it, it's how the papers deal with it and it's how people used it first - however - there is an important difference between the two APIs. The promise constructor is throw safe.
Throw safety
Promises abstract exception handling and are throw safe. If you throw inside a promise chain it will convert that exception into a rejection, quoting the spec:
If either onFulfilled or onRejected throws an exception e, promise2 must be rejected with e as the reason
Let's assume you're parsing JSON from an XHR request:
function get(){
var d = Q.defer();
if(cached) { // use cached version user edited in localStorage
d.resolve(JSON.parse(cached));
} else { // get from server
myCallbackApi('/foo', function(res){ d.resolve(res); });
}
}
Now, let's look at the promise constructor version:
function get(){
return new Promise(function(resolve, reject){
if(cached) { // use cached version user edited in localStorage
resolve(JSON.parse(cached));
} else { // get from server
myCallbackApi('/foo', resolve);
}
});
}
Now, assume somehow your server sent you invalid JSON (or the user edited it to an invalid state) and you cached it.
In the defer version - it throws synchronously. So you have to generally guard against it. In the bottom version it does not. The top version usage would look like:
try{
return get().catch(function(e){
return handleException(e); // can also just pass as function
});
} catch(e){
handleException(e);
}
In the bottom version - the promise constructor will convert throw
s to rejections so it is enough to do:
return get().then(function(e){
return handleException(e);
});
Preventing a whole class of programmer errors from ever happening.
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.
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.
What is the difference between defer object promise and promise from $resource service
The promise returned from $resource
is one someone initially used $q.defer()
(or the newer more modern promise constructor) to create.
That someone is the $http
service used internally inside $resource
- you are using a promise they created for you.
Typically, you only need to use a $q.defer
or the promise constructor at the lowest level of your code when working with async - otherwise you're typically better off using promise chaining. Otherwise you end up with the explicit construction anti-pattern.
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's the difference between a Deferred object and its own promise object?
It creates a "sealed" copy of the deferred value, without the .resolve()
and .reject()
methods. From the documentation:
The
deferred.promise()
method allows an asynchronous function to prevent other code from interfering with the progress or status of its internal request.
It's used when it doesn't make sense for the value to be modified. For example, when jQuery makes an AJAX request it returns a promise object. Internally it .resolve()
s a value for the original Deferred
object, which the user observes with the promise.
What is the difference of returning a promise() or a deferred in jQuery?
So what's the difference of returning
deferred.promise()
or only returndeferred
?
You want to return deferred.promise()
so that the calling code can't call resolve
or reject
or other Deferred-specific methods. That's not something the caller should have access to. It should only be able to consume the promise, not affect its state.
Related Topics
How to Get the Position of an Element After CSS3 Translation in JavaScript
Modify Element :Before CSS Rules Programmatically in React
CSS and Jquery: Spaces Inside Image Name Break Code of Url()
Multiple Slideshows on One Page Makes the First One Not Work Anymore
How to Setup Less Using Only Js
What Does Style.Display = '' Actually Do
Jquery "Blinking Highlight" Effect on Div
Jquery to Change Style Attribute of a Div Class
Cannot Set Property 'Display' of Undefined
Transitionend Event Fires Twice
Resize Cross Domain Iframe Height
How to Fetch an Array of Urls with Promise.All
How to Capitalize the First Letter of Each Word in a String Using JavaScript
Differencebetween the Mouseover and Mouseenter Events
Square Brackets JavaScript Object Key
Putting Datepicker() on Dynamically Created Elements - Jquery/Jqueryui
Should I Use Window.Navigate or Document.Location in JavaScript