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 p1
testP
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 p3
p3.then
with the value resolve
and remember the result as p4
p4.catch
with the value reject
reject
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);
});
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments