在解决初始承诺后如何在迭代数组时链接多个承诺?

How do I chain multiple promises while iterating an array after the initial promise is resolved?

我有一个函数(buildMetaData) 执行以下操作

1. It receives an array(`items`) as a param
2. It invokes an DAO to fetch some data from a downstream service.
3. The downstream service responds with a promise (initial promise).
4. In the "then"(resolving initial promise), I need to modify the array passed in the param and return the modified array.

在第 4 步中,我映射 items 数组,在修改数组元素时,我需要调用另一个函数,该函数 returns 一个 promises 数组。我需要解决这个承诺才能设置数组元素。 我如何将这一系列承诺链接到最初的承诺?

buildMetaData(items) {
   return checkoutDAO.get(items[0].id)
      .then((order) => {
          return items.map((item) => {
              let res = {};
              // some processing 

              const promises = this.buildItemMeta({itemType: item.type, itemId: item.id})

              promises.spread((product, media) => {
                res.size = this.getItemSize(product, media);
              });
              return res;
          });
      });
}

buildItemMeta({itemType, itemId}) {
    const promises = [
      productDAO.get(itemType), // this is a promise
    ];
    promises.push(mediaDAO.get(itemId`)); // this is a promise
    return Promise.all(promises);
}

我希望新数组能够解析 res.size 属性,但实际上 promise.all 正在创建一个新的 promise 实例,而不是链接到初始 promise。

p.s。此项目使用 continuation local storage(cls),cls 与 async/await 存在一些已知问题,因此我无法使用 async/await 解决此问题。

如果这需要进一步解释,请告诉我。感谢您为回答这个问题所做的努力。

这会执行这些步骤,但顺序是异步的。当无法使用 async/await 时,程序性思考可能不是解决异步问题的最佳思考方式。如果您有任何问题,请告诉我。

所以这个:

  1. 它接收一个数组(items)作为参数
  2. 它调用 DAO 从下游服务中获取一些数据。
  3. 下游服务响应承诺(初始承诺)。
  4. 在"then"(解决初始承诺)中,我需要修改参数中传递的数组和return修改后的数组。

现在变成这样:

  1. 它接收一个数组(items)作为参数
  2. 它检索每个项目的元数据并保存创建的 Promises 数组
  3. 它存储对下游服务的调用的承诺。
  4. 所有承诺都已解决
  5. 'then' 传递了项目元数据和顺序,用作合并它们的最后阶段

请注意,我还简化了您的一些代码。

buildMetaData(items) {
  const itemMetaPromises = items.map(item => this.buildItemMeta(item.type, item.id));
  const orderPromise = checkoutDAO.get(items[0].id);
  Promise.all([...itemMetaPromises, orderPromise])
    .then(data => {
       // data[0] = itemMeta([itemType,itemId]), data[1] = order
      //combine order and items here
    });
}

buildItemMeta(itemType, itemId) {
    return Promise.all([productDAO.get(itemType),mediaDAO.get(itemId)]);
}

这是一个显示输出的模拟实现。

function buildMetaData(items) {
  const itemMetaPromises = items.map(item => buildItemMeta(item.type, item.id));
  const orderPromise = checkoutDAO.get(items[0].id);
  Promise.all([...itemMetaPromises, orderPromise])
    .then(data => {
      console.log(data);
    });
}

function buildItemMeta(itemType, itemId) {
  return Promise.all([productDAO.get(itemType), mediaDAO.get(itemId)]);
}

checkoutDAO = {
  get: () => new Promise((resolve) => {
    resolve('order')
  })
}
productDAO = {
  get: () => new Promise((resolve) => {
    resolve('product')
  })
}
mediaDAO = {
  get: () => new Promise((resolve) => {
    resolve('media')
  })
}

items = [{
  type: 'itemType',
  id: 'itemId'
}, {
  type: 'itemType',
  id: 'itemId'
}, {
  type: 'itemType',
  id: 'itemId'
}, {
  type: 'itemType',
  id: 'itemId'
}];


buildMetaData(items);