javascript - 循环中的循环总增量,但之后打印时返回 0
问题描述
我正在创建一个充当股票投资组合经理的 Alexa 应用程序。我有一个功能,它首先检索所有股票和属于用户的股票数量。对于这些股票中的每一个,我必须使用 axios 查询 API 以获取股票的价值,这意味着 axios get 语句嵌套在 forEach 循环中。然后我有一个 totalPrice 变量,它使用股票的总价格递增;这是通过将价格乘以拥有的股票数量 x 得出的
在 forEach 循环结束时,我想打印总价格,这将是投资组合的全部价值
当我在请求语句中打印出 totalPrice 时,它正确地添加了以前的总股票价格,但如果我在 forEach 循环之后打印 totalPrice,它会打印 0
var grandTotal = 0;
data.Items.forEach(function(element,index,array) {
var stock = element.Stock;
var number = element.Number;
var url = `www.api.com/${stock}`;
const getDataValues = async url => {
try {
const response = await axios.get(url);
const data = response.data;
var Price = data.PRICE;
return Price;
} catch (error) {
console.log(error);
}
};
let promiseObject = getDataValues(url);
promiseObject.then(function(result) {
var totalPriceofStocks = result * amount;
grandTotal += totalPriceOfStocks;
console.log(`{grandTotal}`); // This bit accumulates correctly
});
});
console.log(`The grand total is: ${grandTotal}`);
令我困惑的是,虽然数据是异步的,但我认为 using.then
会等到数据被检索到。这似乎是这种情况,因为在 forEach 循环中打印总数时这是有效的。其他有趣的是,在控制台中,“总计为:0”首先打印。
解决方案
最后的 console.log 打印 0 因为它是在你的 Promise 启动后立即执行的(但尚未完成)。
为了等到所有的承诺都完成,那么你可以:
- 将承诺存储在列表中
- 使用Promise.all,它将一个承诺列表作为参数,并在所有承诺都已解决时解决(在您的情况下,当所有 axios 请求都完成时)。
我添加了您的代码的修改示例,以展示如何执行此操作。由于我没有您的数据,我无法对其进行测试,但希望它可以工作。
const promises = []
const getDataValues = async url => {
try {
const response = await axios.get(url);
const data = response.data;
var Price = data.PRICE;
return Price;
} catch (error) {
console.log(error);
}
};
var grandTotal = 0;
data.Items.forEach(function(element,index,array) {
var stock = element.Stock;
var number = element.Number;
var url = `www.api.com/${stock}`;
let promiseObject = getDataValues(url);
promiseObject.then(function(result) {
var totalPriceofStocks = result * amount;
grandTotal += totalPriceOfStocks;
console.log(`${grandTotal}`); // This bit accumulates correctly
return totalPriceOfStocks
});
promises.push(promiseObject)
});
Promise.all(promises)
.then(function (resultValues) {
console.log(`The grand total is: ${grandTotal}`);
let resultSum = 0;
resultValues.forEach(function (value) {
resultSum += value;
})
console.log(`This is also the total: ${resultSum}`);
})
另请注意,我已向您的承诺对象添加了返回值。我有这个展示累积总数而不是依赖全局值的另一种方法。这背后的逻辑是,当 Promise 返回一个值时,该值可用于传递给“then”链接函数的函数。在这种情况下,我们使用 Promise.all,Promise.all 将一个 Promise 的返回值列表传递给它的 'then' 函数。因此,我们可以将 returnValues 参数的元素相加来计算总计。
推荐阅读
- javascript - 在客户端 JavaScript 中自动列出目录内容?
- javascript - Angular2 PWA / Safari 无法在新窗口中打开链接
- vb.net - 如何打印隐含的小数点后 5 到 2 位?
- scala - Scala 期货是否支持非阻塞组合器,例如 firstNCompletedOf 和 firstNSuccCompletedOf?
- c# - 在 C# 中将 int 变量初始化为减一
- c# - 如何使用 Microsoft.Office.Interop.Excel 设置隐藏和空单元格处理
- html - 将水平菜单转换为垂直菜单
- python - 我可以使用类实例的类来提高可读性吗?
- python - 将 Python 模块导入 AWS Lambda
- javascript - 如何防止 node.js 中的竞争条件?