I have multiple arrays of promises
Each array is put inside a Promise.all()
The then()
of each Promise.all()
adds data to a tempObject
I need to set the tempObject
to state after then()
of all Promise.all()
are done executing.
What is the best approach (clean and readable code) to achieve this?
below is my code
callSomeApis(parameter){
let tempArray1 = [];
let tempArray2 = [];
this.props.dispatch(actions.callApi1(parameter)).then(callApi1Result =>{
let callApi1ResultArray = callApi1Result.data.data;
let PromiseArr1 = callApi1ResultArray.map((callApi1ResultArrayItem) => {
return this.props.dispatch(actions.callApi2(callApi1ResultArrayItem.itemId));
});
let PromiseArr2 = callApi1ResultArray.map((callApi1ResultArrayItem) => {
return this.props.dispatch(actions.callApi3(callApi1ResultArrayItem.itemId,parameter));
});
let PromiseArr3 = callApi1ResultArray.map((callApi1ResultArrayItem) => {
return this.props.dispatch(actions.callApi4(callApi1ResultArrayItem.itemId));
});
Promise.all(PromiseArr1).then((callApi2Result) => {
callApi2Result.map((callApi2ResultItem,index) => {
callApi1ResultArray[index].api2Details = callApi2ResultItem.data.data[0];
tempArray2.push({id: callApi2ResultItem.data.data[0].id, text: callApi2ResultItem.data.data[0].text});
});
this.setState(prevState => {
return{
stateKey1: {
...prevState.stateKey1,
innerStateKey1: {
...prevState.stateKey1.innerStateKey1,
list: tempArray2
}
}
}
});
});
Promise.all(PromiseArr2).then((callApi3Result) => {
callApi3Result.map((callApi3ResultItem, index) => {
callApi1ResultArray[index].api3Result = callApi3ResultItem.data.data;
});
});
Promise.all(PromiseArr3).then(callApi4Result => {
callApi4Result.map((callApi4ResultItem,index) => {
callApi1ResultArray[index].api4Result = callApi4ResultItem.data.data;
});
});
/**need to call this after the thens of PromiseArr1, PromiseArr2 and PromiseArr3 are done executing*/
this.setState({
stateKey2:callApi1ResultArray
})
/** */
})
}
Approach 1: In this approach, we will use Promise. all() method which takes all promises in a single array as its input. As a result, this method executes all the promises in itself and returns a new single promise in which the values of all the other promises are combined together.
all() The Promise. all() method takes an iterable of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises. This returned promise will fulfill when all of the input's promises have fulfilled, or if the input iterable contains no promises.
In other words, the Promise. all() waits for all the input promises to resolve and returns a new promise that resolves to an array containing the results of the input promises. In this diagram, the promise2 rejects at t1 with an error .
Final Thoughts: Parallel ProcessingOften Promise. all() is thought of as running in parallel, but this isn't the case. Parallel means that you do many things at the same time on multiple threads. However, Javascript is single threaded with one call stack and one memory heap.
Promise.all
returns a promise so you can do:
const p1 = Promise.all(PromiseArr1).then(...);
const p2 = Promise.all(PromiseArr2).then(...);
const p3 = ...
Promise.all([p1, p2, ...]).then(...);
If all your promises are very similar you can clean it up by creating an array and mapping it to the promises.
If you're able, you can also use async
/await
async function (...) {
const r1 = await Promise.all(...);
// do something with r1
const r2 = await Promise.all(...);
// ...
}
and so on. Make sure you're using Promise.all
on actions that can be parallelized (that also return a Promise
), though.
I find that async
/await
really cleans up some nasty Promise
chains/nesting and helps a lot with readability.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With