Promise.then before resolve

Viewed 75

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

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.

Related