fetch sequently

2019-08-20 04:48发布

问题:

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?

回答1:

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'))
}


回答2:

You need to return promise !!!

You need to know following two facts before understanding the reason.

  1. 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 ...

  1. 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 thens 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.