我正在创建一个Alexa应用程序,该应用程序充当股票的投资组合经理。我有一个函数,该函数首先检索所有股票和属于用户的股票数量。对于每种股票,我必须使用axios查询API以获取股票的价值,这意味着axios get语句嵌套在forEach循环内。然后,我有一个totalPrice变量,该变量使用股票的总价格递增;将价格乘以拥有的股票数量x即可得出
在forEach循环结束时,我要打印totalPrice,这将是投资组合的整个价值
当我在request语句中打印出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}`);
令我困惑的是,尽管数据是异步的,但我认为使用.then
会一直等到检索到数据为止。似乎是这样,因为在forEach循环中打印总计时可以正常工作。有趣的是,在控制台中,“总计为:0”首先打印。
答案 0 :(得分:1)
最后的console.log打印0,因为它在您的诺言开始之后(并且尚未完成)立即执行。
为了等到所有承诺都完成,您可以:
我添加了修改后的代码示例,以演示如何执行此操作。由于我没有您的数据,因此我无法对其进行测试,但希望它能起作用。
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对象添加了返回值。我这样做是为了显示一种积累总计而不是依赖于全局值的替代方法。 其背后的逻辑是,当Promise返回一个值时,该值可用于传递给'then'链接函数的函数。在这种情况下,当我们使用Promise.all时,Promise.all将一个Promise返回值的列表传递给它的'then'函数。因此,我们可以将returnValues参数的元素加在一起以计算总计。
答案 1 :(得分:0)
使用for..of循环,而不是forEach,await应该在其中按预期方式工作
for (const element of data.Items) {
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);
}
};
const result = await getDataValues(url);
var totalPriceofStocks = result * amount;
grandTotal += totalPriceOfStocks;
console.log(`{grandTotal}`);
}