Codes are as following:
var fetch = require('node-fetch')
function fetchA(){
fetch('https://github.com/keegoo')
.then(response => console.log('fetchA'))
.then(fetchB)
.then(fetchC)
.then(() => console.log('hi'))
}
function fetchB(){
fetch('https://github.com/keegoo/trigger')
.then(response => console.log('fetchB'))
}
function fetchC(){
fetch('https://github.com/keegoo/trigger/tree/master/app')
.then(response => console.log('fetchC'))
}
// call
fetchA()
Inside fetchA, I called fetchB and fetchC.
I'm expecting the output should be:
fetchA
fetchB
fetchC
hi
instead, it's:
fetchA
hi
fetchC
fetchB
Why?
If I need the output to be fetchA -> fetchB -> fetchC -> Hi
, what should I do?
Your fetchB
and fetchC
should return the promises from fetch
, otherwise the subsequent calls like .then(fetchB)
are resolved immediately.
function fetchB(){
return fetch('https://github.com/keegoo/trigger')
.then(response => console.log('fetchB'))
}
function fetchC(){
return fetch('https://github.com/keegoo/trigger/tree/master/app')
.then(response => console.log('fetchC'))
}
You need to return promise !!!
You need to know following two facts before understanding the reason.
- return value of a promise(
then
here) will be passed to the next promise(next then
).
Promise.resolve('A')
.then(x => {
console.log(x) // output A
return 'B'
})
.then(x => {
console.log(x) // output B
// no return here !
})
.then(x => {
console.log(x) // output undefined, cause the **previous** `then` didn't return anything
return 'C'
})
.then(x => {
console.log(x) // output C
return 'D'
})// promise chain goes on ...
- a promise chain, e.g.
fetch().then().then().then()
..., will return immediately.
// here blockA simulate a heavy operation: 3000 ms later, 'A' will be returned.
const blockA = new Promise((resolve, reject) => setTimeout(() => resolve('A'), 3000))
blockA
.then(x => {
console.log(x)
return 'B'
})
.then(x => {
console.log(x)
return 'c'
}) // chains goes on ...
console.log('Hello world')
No matter how long the promise chain is, 'Hello world' always output first, which means the promise chain returned immediately. Until blockA
been resolved sometime later, the following then
s will be executed(callback).
In your case:
fetchB
and fetchC
will return immediately, right?
function fetchA(){
fetch('https://github.com/keegoo')
.then(response => console.log('fetchA')) // when 'https://...' responded, this promise been execute, output fetchA
.then(fetchB) // then fetchB be executed, but return immediately.
.then(fetchC) // then fetchC be executed, but return immedidately again.
.then(() => console.log('hi')) // then output 'hi'
}
// sometime in the future, when the `fetch`s inside fetchB and fetchC got responses, the `console.log`s then be executed.
So if you return fetch().then().then()
, the promise chain will be bought to the next promise, and will be resolved fully before moving on.