简体   繁体   中英

Go to the next forEach iteration after promise resolves

I'm going throgh the array of some data and on every iteration I deal with promise.

What I want is to go to the next forEach iteration only when the promise on the current iteration is resolved.

I searched through out different solutions and figured out that usage of for(... of...) instead of forEach could make the trick. But still can't figure it out.

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

Recursion helps:

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)

If you can, i'd recommed an easy to read and understand for of loop with await/async. Notice the top level await is very recent addition, so you should wrap that in some async function (which you'd likely do anyway).

If you cannot use async/await you can use reduce with an initial resolved promise to chain subsequent calls.

Notice that I used a function sleep that resolves a promise after some time. The call to sleep should be interchangeable with axios calls.

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

It looks like nobody posted the specific async/await yet, so this is how you use it with for…of:

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;
  }

  // …
}

This all being placed inside an async function. (Also, {...params } is a bit weird. What's wrong with params directly?)

Just use await on the api call.

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM