Are the following code snippets equivalent?
function doSomething() {
var defer = $q.defer();
foo().then(function() {
bar().then(function() {
defer.resolve();
});
});
return defer.promise;
}
function doSomething() {
return foo().then(bar);
}
A Promise is in one of these states: pending: initial state, neither fulfilled nor rejected. fulfilled: meaning that the operation was completed successfully. rejected: meaning that the operation failed.
A Promise is a JavaScript object that links producing code and consuming code.
Promise resolve() method: Any of the three things can happened: If the value is a promise then promise is returned. If the value has a “then” attached to the promise, then the returned promise will follow that “then” to till the final state. The promise fulfilled with its value will be returned.
Promises are used to handle asynchronous operations in JavaScript. They are easy to manage when dealing with multiple asynchronous operations where callbacks can create callback hell leading to unmanageable code.
There are many differences between these two approaches.
The major difference between the two snippets is that in version 2
your are implicitly passing the resolved value from foo
directly to bar
.
In addition to that doSomething
will resolve whatever bar
will resolve to, whereas in version 1
the result is discarded.
Some additional important points made by Benjamin Gruenbaum:
(a) if bar is a reference error 1 rejects the inner promise and 2 throws.
(b) 1 requires a reference to $q where 2 is implementation agnostic.
(c) version 1 is not exception safe and a rejection will be swallowed where version 2 will let you .catch a rejection. ; There are several smaller differences as well. See stackoverflow.com/questions/22539815
You could also write it like this.
This way you don't get the implicit pass trough of the resolved value from foo
to bar
( it's explicit now ), which can be confusing or easily overlooked. It can also be useful if you want to do something with the resolved values of foo
or bar
before returning them.
function doSomething() {
return foo().then(function(res){
// maybe do something with the result of foo
return bar(res);
}).then(function(res){
// maybe do something with the result of bar
return res;
});
}
Manually creating a deferred object should be kept to a minimum and is generally an anti pattern.
https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern
The key principle being demonstrated here is that a promise will adopt the state of the returned promise ( or thenable ) inside it's resolve method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With