gpt4 book ai didi

javascript - 自异步以来如何优化此代码块

转载 作者:行者123 更新时间:2023-11-30 11:12:10 24 4
gpt4 key购买 nike

var orderItems = userData.shoppingcart;

var totalPrice = 0;
userData.shoppingcart.forEach(function(itemName, i){
_data.read('menuitems', itemName, function(err, itemData){
if(!err && itemData)
{
totalPrice += itemData.price;
if(++i == userData.shoppingcart.length){

// Only here when all the itemNames have been read I should continue

}
}
});
});

如您所见,对 _data.read 的调用是异步的,因为我正在从文件中读取数据。

但我需要等待读取所有文件,这样我才能计算出总价格。这就是为什么我放置该条件 [++i == userData.shoppingcart.length ]。

一般来说,我是 javascript 和 nodejs 的新手,从来都不是很好的编程人员,但无论如何我的观点是我确信这不是一个好方法,如果同时读取两个文件会怎样,然后那个条件永远不会运行或者 totalPrice 的计算做得不好?

有人可以给我一些指导吗?提前致谢!

最佳答案

鉴于您没有指定这是在什么上下文中,我将做一些假设:

  1. 我假设 _data.read() 还不支持返回 promise 。
  2. 我假设此代码需要调用回调函数或返回 promise 。

我(有点天真)的做法是:

  1. orderItems 映射到该商品每个价格的 Promise 中。
  2. 将结果映射到总计
  3. 返回结果 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;

如果你有一个预期的回调(错误,结果),那么做这样的事情:

promiseOfTotal.then(
result => callback(null, result),
error => callback(error, null),
)

如果你需要对结果做更多​​的工作,你可以用另一个来做:

promiseOfTotal.then(
priceSum => {
// Do work here
},
// Optionally handle errors here:
error => {
// Do error handling here.
}
)

请注意,通过使用 promises、箭头函数和数组理解(mapreduce),我们避免了复杂且难以跟踪的变量和循环突变。这是一种“函数式”编程风格,虽然学习起来有些困难,但通常比其他方法更安全、更简洁。我建议花时间了解它的工作原理,因为它会帮助您编写在处理异步性等复杂事物时不太可能出现错误的代码。

最后,我没有运行这段代码。它很可能有一两个错误。如果它不起作用,请随时要求澄清。

祝你好运!

附言我没有开始使用 async/await 因为我认为它不如直接使用 Promises 和使用 Promise.all 无论如何都需要并行性。在这里使用它们绝对有可能取得良好效果,但我会将其作为练习留给 OP。

关于javascript - 自异步以来如何优化此代码块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53252200/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com