承诺解决后,转到下一个forEach迭代

时间:2019-10-03 09:58:30

标签: javascript axios

我要遍历一些数据的数组,在每次处理迭代时,我都会处理promise。

我想要的是仅在解决当前迭代的承诺后才进行下一个forEach迭代。

我搜索了不同的解决方案,并发现使用for(... of ...)而不是forEach可以解决问题。但是仍然无法弄清楚。

const data = ['apple', 'orange', 'banana'];

data.forEach((row, rowIndex) => {
  let params = {
    fruitIndex: rowIndex,
  };

  axios.post('/fruits', { ...params })
    .then(response => {
      // go to the next iteration of forEach only after this promise resolves
    })
    .catch(error => console.log(error))
});

4 个答案:

答案 0 :(得分:2)

递归可以帮助:

const data = ['apple', 'orange', 'banana'];


function request_fruit(n) {
  let params = {
    fruitIndex: n,
  };

  axios.post('/fruits', { ...params })
    .then(response => {
      // Work with recived...
      // ....
      // Request next
      if(n+1<fruits.length) request_fruit(n+1)
    })
    .catch(error => console.log(error))
};
request_fruit(0)

答案 1 :(得分:2)

如果可以的话,我建议您使用await / async轻松阅读和理解循环。请注意,顶层等待是最近添加的,因此您应该将其包装在一些异步函数中(无论如何您都可以这样做)。

如果您无法使用异步/等待,则可以将reduce与最初解决的诺言结合使用,以链接随后的呼叫。

通知,我使用了sleep函数,该函数会在一段时间后解决承诺。对sleep的调用应该可以与axios调用互换。

const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

const data = [1000, 2000, 3000];


function withReduce() {
  console.log('Sequential Promises with Reduce:');

  return data.reduce((previousPromise, ms) => {
    return previousPromise
      .then(() => {
        console.log(`sleeping for ${ms}ms`);
        return sleep(ms);
      });
  }, Promise.resolve());
}

async function withAsync() {
  console.log('Sequential Promises with for of and await:');

  for (let ms of data) {
    console.log(`sleeping for ${ms}ms`);
    await sleep(ms);
  }
}

withReduce().then(withAsync);

答案 2 :(得分:2)

似乎没有人发布过特定的异步/等待,所以这就是您将它用于…的方式:

const data = ['apple', 'orange', 'banana'];

for (const [rowIndex, row] of data.entries()) {
  let params = {
    fruitIndex: rowIndex,
  };

  let response;

  try {
    response = await axios.post('/fruits', { ...params });
  } catch (error) {
    console.log(error);
    continue;
  }

  // …
}

所有这些都放在异步函数中。 (另外,{ ...params }有点怪。直接params怎么了?)

答案 3 :(得分:-1)

只需在api调用上使用await。

function postFruitData(){
    const data = ['apple', 'orange', 'banana'];

    data.forEach(async (row, rowIndex) => {
      let params = {
        fruitIndex: rowIndex,
      };

      const response = await axios.post('/fruits', { ...params })
    });
}