wait for one fetch to finish before starting the next

回眸只為那壹抹淺笑 提交于 2021-01-06 12:19:32

问题


I have a list of data that I am sending to google cloud. My current code looks like this:

const teams = ['LFC', 'MUFC', 'CFC'];

teams.forEach(team => {
    fetch({
      url: URL,
      method: 'PUT',
      body: team
    });
})

This works with one team but it is timing out if sending multiple files and the files are bigger. I am sending images over and not strings. To solve this I need to POST the data one file by one, and wait for the previous POST to complete before sending the subsequent one. Can anyone advise the best way of doing this?

Worth noting that I don't have any control over the number of files that are uploaded.


回答1:


Use a reduce instead of forEach, with .then().

The following will store the promise of the last fetch in acc (the accumulator parameter of reduce), and appends the new fetch inside of a then listener, to ensure that the previous fetch is finished:

const teams = ['LFC', 'MUFC', 'CFC'];

teams.reduce((acc,team) => {
    return acc.then(()=>{
      return fetch({
        url: URL,
        method: 'PUT',
        body: team
      });
    })
}, Promise.resolve())
.then(()=>console.log("Everything's finished"))
.catch(err=>console.error("Something failed:",err))

//Simulate fetch:
const fetch = team => new Promise(rs => setTimeout(() => {rs();console.log(team)}, 1000))

const teams = ['LFC', 'MUFC', 'CFC'];

teams.reduce((acc, team) => {
  return acc.then(() => {
    return fetch({
      url: URL,
      method: 'PUT',
      body: team
    });
  })
}, Promise.resolve())
  .then(() => console.log("Everything's finished"))
  .catch(err => console.error("Something failed:", err))

Or, even better, if you can, use async/await (it's more readable):

const teams = ['LFC', 'MUFC', 'CFC'];

async function upload(teams){
  for(const team of teams){
    await fetch({
      url: URL,
      method: 'PUT',
      body: team
    });
  }
}

upload(teams)
.then(()=>console.log("Everything's finished"))
.catch(err=>console.error("Something failed:",err))

//Simulate fetch:
const fetch = team => new Promise(rs => setTimeout(() => {rs();console.log(team)}, 1000))

const teams = ['LFC', 'MUFC', 'CFC'];

async function upload(teams) {
  for (const team of teams) {
    await fetch({
      url: URL,
      method: 'PUT',
      body: team
    });
  }
}

upload(teams)
  .then(() => console.log("Everything's finished"))
  .catch(err => console.error("Something failed:", err))



回答2:


You can use async/await with a for...of loop. Each call will "hold" the loop, until it's done, and then the loop will continue the next call:

const teams = ['LFC', 'MUFC', 'CFC'];

async function send(teams) {
  for (const team of teams) {
    await fetch({
      url: URL,
      method: 'PUT',
      body: team
    });
  }
}



回答3:


You can make use of async/await, as follows:

const teams = ['LFC', 'MUFC', 'CFC'];

teams.forEach(async (team) => {
    await fetch({
      url: URL,
      method: 'PUT',
      body: team
    });
})


来源:https://stackoverflow.com/questions/58492609/wait-for-one-fetch-to-finish-before-starting-the-next

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!