I wanted to know why the promise below both call the catch() and then() method.
function testpromise(){
return new Promise((resolve, reject)=>{
reject("Error");
})
}
testpromise()
.catch((err)=>{console.log(err)})
.then(()=>{console.log("Then")})
I wanted to know why the promise below both call the catch() and then() method.
function testpromise(){
return new Promise((resolve, reject)=>{
reject("Error");
})
}
testpromise()
.catch((err)=>{console.log(err)})
.then(()=>{console.log("Then")})
But why this one doesn't ? (I only moved the .then() method before the .catch() one).
function testpromise(){
return new Promise((resolve, reject)=>{
reject("Error");
})
}
testpromise()
.then(()=>{console.log("Then")})
.catch((err)=>{console.log(err)})
Is this a bug ? It's kind weird that I can't get the catch() method before the .then(). For me putting catch before then allow me to quickly check if I handle possible errors correctly. I have dozens of promises wrote like so and I just noticed that it will also call my .then() method right away, which is not good.
Share Improve this question asked Apr 3, 2021 at 12:10 Trystan SarradeTrystan Sarrade 74412 silver badges25 bronze badges 1-
1
This is not a bug...it is by design.
catch()
returns a promise also which will be picked up by next then() in the chain if you don't throw again inside the catch. – charlietfl Commented Apr 3, 2021 at 12:17
3 Answers
Reset to default 9A catch returns a promise so unless you throw or return another rejected promise it will resolve to the next then() in the chain
Following contrived example should help you visualize it
testpromise()
.catch((err) => {
console.log('First catch=', err)
return 'Catch message'; // implicit return value, with no return next then receives undefined
})
.then((fromCatch) => {
console.log("from first catch =", fromCatch)
})
.then(testpromise) // return another rejected promise to next catch
.then(() => console.log('Not called'))
.catch((err) => {
console.log('Second catch');
throw 'New Error'
})
.then(() => console.log('Not called #2'))
.then(() => console.log('Not called #3'))
.catch(err => console.log('Final catch =', err))
function testpromise() {
return new Promise((resolve, reject) => {
reject("Error");
})
}
Consider the following code:
try {
throw new Error("catch me if you can!");
} catch (err) {
// whatever
}
console.log("hi");
Because that is the synchronous equivalent of this:
Promise.reject(new Error("catch me if you can!"))
.catch(_ => { /* whatever */ })
.then(_ => console.log("hi"));
Each time you add a .then
or .catch
it returns a new promise, it doesn't modify the old one in place. So it's not that the order is wrong, it's that it matters. Otherwise you couldn't do something like this:
fetch(someURL)
.then(response => response.json())
.then(doSomethingWithJSON)
.catch(err => {
handleRequestFailure(err);
console.error(err);
return err;
})
.then(result => {
if (result instanceof Error) {
return fallbackRequest();
}
})
.catch(handleFallbackError);
A .catch() is really just a .then() without a slot for a callback function for the case when the promise is resolved.
MDN Promises Documentation
Think of the .then()
function as a chain, each one does something according to the resolved value, and passes the returned value to the next .then()
in the chain, or if an error thrown, to the .catch()
method.