Javascript 承诺。都有附加价值
初学承诺,愿意学习。 我有一组ShopID:Javascript 承诺。都有附加价值,javascript,node.js,promise,es6-promise,Javascript,Node.js,Promise,Es6 Promise,初学承诺,愿意学习。 我有一组ShopID: let shopIdsArray = ['shop1','shop2','shop3']; 还有一个外部承诺电话 getProducts(shopId, 'products') //promise returns the products of this shop 不幸的是,承诺不返回shopId,只返回产品,因此我必须以某种方式保留shopId,并在承诺完成后将其与产品一起存储。 我目前的方法是使用每个shopId调用promise,并将每个p
let shopIdsArray = ['shop1','shop2','shop3'];
还有一个外部承诺电话
getProducts(shopId, 'products') //promise returns the products of this shop
不幸的是,承诺不返回shopId,只返回产品,因此我必须以某种方式保留shopId,并在承诺完成后将其与产品一起存储。
我目前的方法是使用每个shopId调用promise,并将每个promise调用的结果添加到ShopAndProductsArray,如下所示:
shopsAndProductsArray.push({
"id":shopId,
"products":products
});
稍后,我的“包装承诺”应该归还成品商店和产品
我当前的代码(节点,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?
});
}
);
解析时,shopsAndProductsArray…不是空的,但包含与ShopIdArray相同数量的条目,但数组项未定义。我可能应该先将承诺放入数组,然后在Promise.all中处理它们,但在那一点上,我丢失了承诺所属的商店id的引用
我阅读了许多关于迭代和承诺的其他例子,并尝试了许多其他方法,但似乎我还没有完全理解在哪一点上被称为什么。我确信用我的方式填充promises数组是错误的,但我不知道如何调用Promise.all
我想我可以把我的问题缩小到:
我认为你的答案基本上是一样的,而且都解释得很透彻。我给justelouise打上“接受”复选标记,因为她似乎是第一个,而Felix Kling的声望稍高一些。我认为您可以简化您的功能:
return Promise.all(shopIdsArray.map(shopId => {
return getProducts(shopId).then((products) => {
return {
id: shopId,
products,
};
});
}));
Promise.all返回一个Promise数组,当您通过map函数在数组中进行迭代时,会对每个店铺id执行in-getProducts调用。返回产品数据后,您仍然可以使用相应的店铺id访问该产品,并返回一个由id和结果组成的新对象
return {
id: shopId,
products,
};
最后,Promise.all返回一个数组,其中包含在其中执行的每个Promise的返回值。我认为您可以将函数简化为:
return Promise.all(shopIdsArray.map(shopId => {
return getProducts(shopId).then((products) => {
return {
id: shopId,
products,
};
});
}));
Promise.all返回一个Promise数组,当您通过map函数在数组中进行迭代时,会对每个店铺id执行in-getProducts调用。返回产品数据后,您仍然可以使用相应的店铺id访问该产品,并返回一个由id和结果组成的新对象
return {
id: shopId,
products,
};
最后,Promise.all返回一个数组,其中包含在其中执行的每个Promise的返回值。您的代码可以简化为:
updateProducts = Promise.all(
['shop1','shop2','shop3'].map(
id => getProducts(id, 'products').then(products => ({id, products}))
)
);
这和你的方法完全一样,只是没有那么冗长
由于Promise.all
已经返回了一个承诺,因此没有必要在其周围添加新承诺(…)
如果要将数组的每个元素转换为其他元素,则array#map
是一种更有用的方法。它将传递的回调应用于数组的每个元素,并返回其返回值的数组。在您的案例中,您希望为每个店铺ID创建一个承诺,这就是为什么
['shop1','shop2','shop3'].map(id => getProducts(id, 'products'))
是的
现在,由于您不仅要获取产品,还要获取ID,我们必须稍微修改getProducts
的结果,这就是
.then(products => ({id, products}))
是的。这没什么特别的。我们只返回一个具有两个属性id
和products
的对象,而不仅仅是products
数组
使用
Promise.all
和Array#map
您不需要“手动”跟踪承诺(promisesArray
)和结果(shopsAndProductsArray
)。您的代码可以简化为:
updateProducts = Promise.all(
['shop1','shop2','shop3'].map(
id => getProducts(id, 'products').then(products => ({id, products}))
)
);
这和你的方法完全一样,只是没有那么冗长
由于Promise.all
已经返回了一个承诺,因此没有必要在其周围添加新承诺(…)
如果要将数组的每个元素转换为其他元素,则array#map
是一种更有用的方法。它将传递的回调应用于数组的每个元素,并返回其返回值的数组。在您的案例中,您希望为每个店铺ID创建一个承诺,这就是为什么
['shop1','shop2','shop3'].map(id => getProducts(id, 'products'))
是的
现在,由于您不仅要获取产品,还要获取ID,我们必须稍微修改getProducts
的结果,这就是
.then(products => ({id, products}))
是的。这没什么特别的。我们只返回一个具有两个属性id
和products
的对象,而不仅仅是products
数组
使用
Promise.all
和Array#map
您不需要“手动”跟踪承诺(promisesArray
)和结果(shopsAndProductsArray
)。您正在调用shopsAndProductsArray.push(ExchangeInfo对象)
但是您创建的对象被分配给shopInfoObject
。您所有的承诺都被解析为未定义的,因为您的。然后(products=>
不会返回任何内容…这就是为什么shopsAndProductsArray
是一个未定义的函数数组(shopsAndProductsArray)
注意:你的const shopsAndProductsArray=[];
从来没有被用于任何东西——除了console.logging,var updateProducts=Promise.all(['shop1','shop2','shop3'].map(id=>getProducts(id,'products')。然后(products=>({id,products})));
可能就是你想要的wanted@Felix,我更正了代码。您正在呼叫shopsAndProductsA