Need some help understanding the Promise object. Consider the following code block:
new Promise(function (resolve, reject) {
reject(1);
}).then(function (v) {
console.log("resolved:", v);
return v;
}, function (v) {
console.log("rejected:", v);
return false;
}).then(function (v) {
console.log("chained then resolved: ", v);
}, function (v) {
console.log("chained then rejected: ", v);
});
I was expecting the above to produce the following result:
rejected: 1
chained then rejected: false
However, it is producing:
rejected: 1
chained then resolved: false
Why is it invoking the resolved handler of the chained then? Running a similar form with jQuery’s Deferred construct works as intended. What am I missing?
The value returned in a .then will be the resolved/rejected value of the promise returned by .then; in the example above, you get “test2 resolved: false” at the end because it is returning false above it. (This is just a typical return value though, I believe there are special return/resolve/reject rules when passing/returning other promises and stuff… The docs I linked above probably have more details on that.)
Thanks @quicksilver! I never usually return from the callbacks so this is very informative. (im a deferred resolver, as i do same with angular framework)
Ok. I’ve read up on the topic and can now say I understand why I was having difficulties with chained ES6 Promises.
To keep it short and succint, when using then in the form (success, failure) one has to throw an exception inside the failure handlers so as force the failure to propagate down the promise chain. Not throwing an exception leads the promise engine to assume that the error was absorbed and dealt with, and thus the promise behaves as if it had resolved instead. Specifically, the following works:
new Promise(function (resolve, reject) {
console.log("rejecting");
reject(false);
}).then(function (v) {
console.log("resolved:", v);
return v;
}, function (v) {
console.log("rejected:", v);
throw(v); // throw!
}).then(function (v) {
console.log("chained then resolved: ", v);
}, function (v) {
console.log("chained then rejected: ", v);
// throw(v);
});
However, this is considered an anti-pattern. The right way to use the ES6 Promise is as given:
Using the form above, the then are given just one handler, which are invoked when the promise resolves, and one must rely on catch to trap promise rejections or errors.