Ok. I’ve read up on the topic and can now say I understand why I was having difficulties with chained ES6 Promise
s.
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:
new Promise(function (resolve, reject) {
resolve(1);
}).then(function (v) {
console.log("first then:", v);
return new Promise(function (resolve, reject) {
reject(false);
});
}).then(function (v) {
console.log("second then: ", v);
}).then(function (v) {
console.log("third then: ", v);
}).catch(function (v) {
console.error("third catch: ", v);
});
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.
Quite a nice and clean design, actually.