Promise在resolve之前调用then

3
我有一个对象数组,每个对象都需要从API调用中获取数据。
每个对象的API端点都不同。
我正在迭代对象数组并为每个对象创建一个Promise。
然后我使用Promise.all传递Promise数组。
一旦Promise解决了,我需要使用它们各自的数据更新原始的对象数组。为了避免两次迭代对象数组,我在Promise解决之前将其then的结果分配给了(为了更好地说)该Promise。
这样做可以工作,但是这种方法是否存在任何问题?
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);
};

我正在分配...在Promise解决之前,将回调传递给then的结果。传递给then的回调在Promise解决后被调用。除非您想在所有请求完成后执行某些操作,否则不需要Promise.all。如果在您的情况下需要Promise.all,那么您可能希望返回Promise.all的结果而不仅仅是等待它。这将允许调用代码在请求完成后执行某些操作。还要记得处理错误。 - Yousaf
@Yousaf 目前代码的编写方式,错误处理已经发生。尽管 OP 忽略了 Promise.all(promises) 返回的解决结果,但由于 await 的存在,如果 service[object.serviceFunc](object.id) 返回的任何 Promise 被拒绝,updateData 将被拒绝。 - t.niese
@t.niese 对的,但是如果 async 函数 updateData 返回的 Promise 被拒绝了,调用代码需要处理被拒绝的 Promise。 - Yousaf
2个回答

3

不,一切都好,但我鼓励您在整个实现中使用async/await。就像这样:

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

3
注意:这种方法很可能比并行发出请求并两次迭代数组的方法更慢。 - Yousaf

1

它能够正常工作,但这种方法是否有任何缺陷呢?

代码本身是好的,但这可能会存在潜在问题,取决于调用方(您如何处理updateData以及传递给函数的对象是否已经更新)。

关于代码本身:我可能会使用map而不是forEach,这将允许您在回调函数中使用await,并使其在意外中断Promise链时更加容错。

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

如果object.data === undefined为假,那么返回的值是undefined,但这不是问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接