Promises.all 附加值

use*_*267 2 javascript node.js promise es6-promise

新承诺,想学习。我有这个 shopIds 数组:

let shopIdsArray = ['shop1','shop2','shop3'];
Run Code Online (Sandbox Code Playgroud)

和一个外部承诺调用

getProducts(shopId, 'products') //promise returns the products of this shop
Run Code Online (Sandbox Code Playgroud)

不幸的是,承诺不返回 shopId,只返回产品,所以我必须以某种方式保留 shopId 并在承诺完成后将其与产品存储在一起。我目前的方法是使用每个 shopId 调用 promise,并将每个 promise 调用的结果添加到 shopAndProductsArray 中,如下所示:

shopsAndProductsArray.push({
    "id":shopId,
    "products":products
}); 
Run Code Online (Sandbox Code Playgroud)

稍后,我的“包装承诺”应该返回完成的shopsAndProductsArray。

我当前的代码(节点,ES6)如下所示:

updateProducts = new Promise(

    function (resolve, reject) {
        let shopIdsArray = ['shop1','shop2','shop3'];
        const shopsAndProductsArray = [];
        let promisesArray = [];

        shopIdsArray.forEach((shopId) => {
            let promise = getProducts(shopId, 'products')
                    .then((products) => {
                        const shopInfoObject = {
                                 "id":shopId,
                                 "products":products
                        };
                        console.log("sio: ",shopInfoObject); //prints shopIds and products fine.
                        shopsAndProductsArray.push(shopInfoObject);
                        promisesArray.push(promise);
                    });

        });

        Promise.all(promisesArray)
            .then(function (shopsAndProductsArray) {
                resolve(shopsAndProductsArray); //the shopsAndProductsArray is undefined?
            });
    }
);
Run Code Online (Sandbox Code Playgroud)

解析时,shopsAndProductsArray 是...不为空,但包含与 shopIdsArray 相同数量的条目,但数组项未定义。我可能应该先将承诺放入一个数组中,然后在 Promise.all 中处理它们,但此时我丢失了对承诺所属商店 ID 的引用。

我阅读了很多其他关于迭代和承诺的例子,并尝试了很多其他的方法,但似乎我还没有完全理解在那个时候叫做什么。我确信以我的方式填充 promises 数组是错误的,但我不知道如何调用 Promise.all。

我想我可以将我的问题缩小到:

  1. 我应该如何遍历 shopIds,并为每个调用 promise?
  2. 一旦承诺返回产品列表,如何保留 shopId?
  3. 处理完所有 shopId 后,如何返回 shopId 和产品数组?

在此先感谢您的帮助。

编辑:非常感谢,justelouise 和 Felix Kling。我知道我把事情复杂化了,但无法将手指放在什么地方。多亏了你的例子,我现在明白我错过了什么。我认为你的答案本质上是平等的,并且都得到了彻底的解释。我给 justelouise 打勾,因为她似乎是第一个,而 Felix Kling 的声望 O_o 稍高一些。

jus*_*ise 6

我认为你可以简化你的功能:

return Promise.all(shopIdsArray.map(shopId => {
  return getProducts(shopId).then((products) => {
    return {
      id: shopId,
      products,
    };
  });
}));
Run Code Online (Sandbox Code Playgroud)

Promise.all返回一个在您通过 map 函数遍历数组时创建的承诺数组,其中在getProducts调用中为每个商店 ID 执行。返回产品数据后,您仍然可以使用相应的商店 id 访问它并返回一个由 id 和结果组成的新对象

return {
  id: shopId,
  products,
};
Run Code Online (Sandbox Code Playgroud)

最后, Promise.all 返回一个数组,其中包含在其中执行的每个 Promise 的返回值。