дождитесь окончания одной выборки перед началом следующей - PullRequest
0 голосов
/ 21 октября 2019

У меня есть список данных, которые я отправляю в облако Google. Мой текущий код выглядит следующим образом:

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

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

Это работает с одним team, но это время ожидания, если отправка нескольких файлов и файлы больше. Я посылаю изображения поверх, а не строки. Чтобы решить эту проблему, мне нужно POST данных один файл за другим, и дождаться завершения предыдущего POST перед отправкой следующего. Кто-нибудь может посоветовать лучший способ сделать это?

Стоит отметить, что я не могу контролировать количество загружаемых файлов.

Ответы [ 3 ]

6 голосов
/ 21 октября 2019

Используйте reduce вместо forEach, с .then().

Следующее будет хранить обещание последнего fetch в acc (параметр аккумулятора reduce)и добавляет новый fetch внутри then слушателя, чтобы завершить предыдущий fetch:

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

Или, еще лучше, если вы можете, используйте async/await (это более читабельно):

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))
4 голосов
/ 21 октября 2019

Вы можете использовать async / await с циклом for .... Каждый вызов будет «удерживать» цикл до завершения, а затем цикл продолжит следующий вызов:

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

async function send(teams) {
  for (const team of teams) {
    await fetch({
      url: URL,
      method: 'PUT',
      body: team
    });
  }
}
0 голосов
/ 21 октября 2019

Вы можете использовать async / await следующим образом:

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

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