I have an array of objects that each need data from an api call.
The api endpoint is different for each object.
I am iterating the array of objects and creating a promise for each.
I am then using Promise.all passing an array of promises.
Once the promises have resolved, I need to update the original array of objects with their respective data. To prevent iterating the object array twice, I am assigning (for want of a better word) the result of then on the Promise before it is resolved.
It works, but are there any pitfalls with this approach?
updateData = async (objects) => {
const promises = [];
objects.forEach(object => {
if (object.data === undefined) {
const service = this.serviceFactory.getService(object.serviceKey);
promises.push(service[object.serviceFunc](object.id).then(data => object.data = data));
}
});
await Promise.all(promises);
};
No, everything is fine, but I would encourage you to use async/await for whole implementation. Something like this:
const processObject = async (object) => {
if (object.data === undefined) {
const service = this.serviceFactory.getService(object.serviceKey);
const data = await service[object.serviceFunc](object.id);
object.data = data
}
return object;
}
updateData = async (objects) => {
const promises = objects.map(processObject);
const processedObjects = await Promise.all(promises);
};
It works, but are there any pitfalls with this approach?
The code shown itself is fine, whether this could have a pitfall depends more on the calling side (how you handle the updateData
and if it is clear that the objects passed to the function are updated).
Regarding the code itself: I would probably use a map
instead forEach
, which would allow you to use await
within that callback, and makes it a bit less error-prone with regard to accidentally breaking the Promise chain within the callback.
updateData = async(objects) => {
const promises = objects.map(async (object) => {
if (object.data === undefined) {
const service = this.serviceFactory.getService(object.serviceKey);
object.data = await service[object.serviceFunc](object.id);
}
});
await Promise.all(promises);
};
In the case object.data === undefined
is false, the returned value is undefined
, but that isn't a problem.