鉴于您没有指定这是在什么上下文中,我将做一些假设:
- 我认为
_data.read() 尚不支持返回承诺。
- 我假设此代码需要调用回调函数或返回承诺。
我(有点天真)的方法是:
- 将
orderItems 映射到该项目的每个价格的 Promise 中。
- 将结果映射到总数中
- 返回结果承诺或调用回调。
这是一个带注释的示例,说明您可以如何做到这一点:
// Promise.all takes an array of promises and returns
// a new promise that completes when all the promises in the array are complete.
const promiseOfPrices = Promise.all(
// Here we map all the items in the shopping cart into promises for each of their prices
userData.shoppingcart.map(
// The Promise object takes a single function that it will immediatly call with functions to resolve or
// reject the promise. I suggest reading up on Promises if you're not familiar with them.
itemName => new Promise((resolve, reject) => {
// Here, we have a `reject` and `resolve` function that will each complete the new promise,
// either in success or error respectfully.
// Do the actual read of your file or database or whatever
_data.read('menuitems', itemName, (err, itemData) => {
// If there was an error, reject this promise.
if (err) reject(err);
// Otherwise, we're successful and we resolve with the price of the item
else resolve(itemData.price);
});
})
)
);
// Now, we have a promise (promiseOfPrices) for all the prices of the items in the cart. We use `then` which will
// perform a transform on the result, much like the `map` function on an Array.
const promiseOfTotal = promiseOfPrices.then(
// Here we use the `Array.reduce` function to succinctly sum the values in the array.
arrayOfCartItemPrices => arrayOfCartItemPrices.reduce(
// For each item, reduce calls our function with the current sum and an item in the array. We produce a new
// sum by adding the sum to the item price.
(sum, itemPrice) => sum + itemPrice,
// This is the initial value for sum, 0.
0
)
);
如果你可以返回一个promise,而你只想返回总数,那么
return promiseOfTotal;
如果你有一个期望 (err, result) 的回调,那么做这样的事情:
promiseOfTotal.then(
result => callback(null, result),
error => callback(error, null),
)
如果你需要对结果做更多的工作,你可以用另一个 then 来做:
promiseOfTotal.then(
priceSum => {
// Do work here
},
// Optionally handle errors here:
error => {
// Do error handling here.
}
)
请注意,通过使用承诺、箭头函数和数组推导(map 和 reduce),我们可以避免复杂且难以跟踪的变量和循环突变。这是一种“函数式”编程风格,虽然有点难学,但通常比其他方法更安全、更干净。我建议花点时间了解它是如何工作的,因为它可以帮助您编写在处理异步等复杂问题时不太可能出现错误的代码。
最后,我还没有运行这段代码。它很可能有一两个错误。随时要求澄清或如果它不起作用。
祝你好运!
附:我没有使用async/await,因为我认为它不如直接使用 Promises 清晰,并且无论如何都需要使用Promise.all 来实现并行性。在这里完全可以使用它们来获得良好的效果,但我将把它作为练习留给 OP。