Try this piece of code on console tab of Chrome or Firefox
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
reject(10);
}, 1000)
})
p.then(function(res) { console.log(1, 'succ', res) })
.catch(function(res) { console.log(1, 'err', res) })
.then(function(res) { console.log(2, 'succ', res) })
.catch(function(res) { console.log(2, 'err', res) })
The result will be
1 "err" 10
2 "res" undefined
I've tried many other examples but it seems that the first then()
returns a promise that always resolves and never rejects. I've tried this on Chrome 46.0.2490.86 and Firefox 42.0. Why does this happen? I thought that then()
and catch()
can be chain multiple times?
Just like in the synchronous code:
try {
throw new Error();
} catch(e) {
console.log("Caught");
}
console.log("This still runs");
Code that runs after the exception has been handled will run - this is because exceptions are an error recovery mechanism. By adding that catch you signaled that the error has been handled. In the synchronous case we handle this by rethrowing:
try {
throw new Error();
} catch(e) {
console.log("Caught");
throw e;
}
console.log("This will not run, still in error");
Promises work similarly:
Promise.reject(Error()).catch(e => {
console.log("This runs");
throw e;
}).catch(e => {
console.log("This runs too");
throw e;
});
As a tip - never reject with non-Error
s as you lose a lot of useful stuff like meaningful stack traces.
Why does this happen? I thought that then() and catch() can be chain multiple times?
@Benjamin is right, +1, but to put it in another way, these are the rules:
- If you add
then
multiple times, you are chaining methods that should be called in sequence, until an exception is thrown. Exceptions in the then
chain must be handled by catch
declared after the then
. If there's no catch
after the then
, this error will be triggered: Uncaught (in promise) Error(…)
.
- If you add
catch
multiple times, you are chaining methods that should be called when something goes wrong (in the then
functions before). However, the second catch
in the chain will only be called if the first one re-throw the exception, and so forth.
- When
catch
is triggered, the chain resumes on the next then
declared after the catch
.