I want to chain 3 promises together but there's some behaviour I can't figure out regarding the resolve and reject functionality. I've simplified my code in order to ask the question:
function testP(num) {
return new Promise((resolve, reject) => {
console.log('Do Work', num);
reject(num);
});
}
function testPromises() {
return new Promise((resolve, reject) => {
testP(1)
.then(testP(2))
.then(testP(3))
.then(resolve)
.catch(reject);
});
};
const theTest = testPromises().then(()=>{
console.log("all done");
}).catch(err => {
console.log("ERR", err);
});
And what I'm seeing in my output is:
Do Work 1
Do Work 2
Do Work 3
ERR 1
Why does the code get to Do Work 2 and Do Work 3 if the first promise hits reject immediately? My understanding was that the then functions wait for the promise to resolve or reject before executing.
Because when you do
.then(testP(2))
you call testP immediately and unconditionally, passing in 2, and then pass its return value into .then, exactly the way foo(bar()) calls bar and passes its return value into foo.
This code:
testP(1)
.then(testP(2))
.then(testP(3))
.then(resolve)
.catch(reject);
is evaluated like this (some minor details omitted):
testP with the value 1 and remember the resulting value as p1testP with the value 2p1.then with the result of that call and remember the resulting value as P2testP with the value 3p2.then with the result of that call and remember the resulting value as p3p3.then with the value resolve and remember the result as p4p4.catch with the value rejectreject function from the first call to testP with the value 1reject from testPromises with the value 1If you want that testP to wait until the first one is settled, you don't call it, you pass a reference to it:
.then(testP)
If you want it to have an argument baked in, use bind:
.then(testP.bind(null, 2))
or an inline function:
.then(function() {
return testP(2);
})
Example (requires a browser with Promise):
function testP(num) {
return new Promise((resolve, reject) => {
console.log('Do Work', num);
reject(num);
});
}
function testPromises() {
return new Promise((resolve, reject) => {
testP(1)
.then(testP.bind(null, 2))
.then(testP.bind(null, 3))
.then(resolve)
.catch(reject);
});
};
const theTest = testPromises().then(()=>{
console.log("all done");
}).catch(err => {
console.log("ERR", err);
});
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