Reputation: 1075
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))
});
Upvotes: 1
Views: 550
Reputation: 155
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 })
});
}
Upvotes: -1
Reputation: 224932
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?)
Upvotes: 2
Reputation: 6253
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);
Upvotes: 2
Reputation: 1012
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)
Upvotes: 3