2 回答

TA貢獻(xiàn)1811條經(jīng)驗 獲得超5個贊
我假設(shè)這Product.getProductDetails()是一個異步方法(它看起來像是對 API 的查詢)。
console.log()不是“在for循環(huán)之前運行”,只是執(zhí)行的任務(wù)Product.getProductDetails()正在異步處理。
由于該方法似乎也適用于回調(diào),因此實現(xiàn)您的目標(biāo)的一種方法是對每個調(diào)用進(jìn)行承諾,然后通過使用方法Product.getProductDetails()將所有承諾壓縮為一個承諾。Promise.all()
這樣的事情應(yīng)該可以解決問題:
Cart.getCompleteCart((cart) => {
const promises = [];
for (let prod of cart.products) {
promises.push(
new Promise((resolve) => {
Product.getProductDetails(prod.productId, (productDetails) => {
resolve({
product: productDetails,
productCount: prod.productCount
});
});
})
);
}
Promise.all(promises).then((products) => {
console.log('Products are ->', products);
});
});
或者:
Cart.getCompleteCart((cart) => {
Promise.all(
cart.products.map((prod) => {
return new Promise((resolve) => {
Product.getProductDetails(prod.productId, (productDetails) => {
resolve({
product: productDetails,
productCount: prod.productCount
});
});
});
})
).then((products) => {
console.log('Products are ->', products);
});
});

TA貢獻(xiàn)1848條經(jīng)驗 獲得超2個贊
Promise.all幾乎是為這個確切的用例而設(shè)計的:
// A dummy "Product" with a dummy "getProductDetails" implementation
// so that we can have a working test example
let Product = {
getProductDetails: (productId, callback) => {
setTimeout(() => {
callback({ type: 'productDetails', productId });
}, 100 + Math.floor(Math.random() * 200));
}
};
// This is the function you're looking for:
let getCompleteCart = async (cart) => {
return Promise.all(cart.products.map(async ({ productId, productCount }) => ({
product: await new Promise(resolve => Product.getProductDetails(productId, resolve)),
productCount
})));
}
let exampleCart = {
products: [
{ productId: 982, productCount: 1 },
{ productId: 237, productCount: 2 },
{ productId: 647, productCount: 5 }
]
};
getCompleteCart(exampleCart).then(console.log);
細(xì)分getCompleteCart:
let getCompleteCart = async (cart) => {
return Promise.all(cart.products.map(async ({ productId, productCount }) => ({
product: await new Promise(resolve => Product.getProductDetails(productId, resolve)),
productCount
})));
}
Promise.all( mdn ) 是專門為等待承諾數(shù)組中的每一個承諾而構(gòu)建的
我們需要提供一個 Promise 數(shù)組給Promise.all. 這意味著我們需要將數(shù)據(jù)數(shù)組 ( cart.products) 轉(zhuǎn)換為 Promises 數(shù)組;Array.protoype.map是這方面的完美工具。
提供的函數(shù)cart.products.map將購物車中的每個產(chǎn)品轉(zhuǎn)換為看起來像的對象{ product: <product details>, productCount: <###> }。
這里棘手的事情是獲取“product”屬性的值,因為這個值是異步的(由回調(diào)返回)。Product.getProductDetails以下行使用 Promise 構(gòu)造函數(shù) ( mdn )創(chuàng)建一個解析為由 返回的值的promise :
new Promise(resolve => Product.getProductDetails(productId, resolve))
await關(guān)鍵字允許我們將此承諾轉(zhuǎn)換為它產(chǎn)生的未來值。我們可以將此未來值分配給“product”屬性,而“productCount”屬性只是從購物車中的原始商品復(fù)制而來:
{
product: await new Promise(resolve => Product.getProductDetails(productId, resolve)),
productCount
}
為了console.log在正確的時間運行,我們需要等待所有產(chǎn)品詳細(xì)信息完成編譯。幸運的是,這是由getCompleteCart. 我們可以console.log在適當(dāng)?shù)臅r候通過等待getCompleteCart來解決。
有兩種方法可以做到這一點:
使用Promise.prototype.then(mdn):
getCompleteCart(exampleCart).then(console.log);
或者,如果我們在async上下文中,我們可以使用await:
let results = await getCompleteCart(exampleCart);
console.log(results);
添加回答
舉報