簡體   English   中英

對於循環,循環中的總增量為零,但隨后打印時返回0

[英]For loop total increments in loop, but when printing afterwards returns 0

我正在創建一個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”首先打印。

最后的console.log打印0,因為它在您的諾言啟動后(尚未完成)立即執行。

為了等到所有承諾都完成,您可以:

  1. 將承諾存儲在列表中
  2. 使用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對象添加了返回值。 我這樣做是為了顯示一種積累總計而不是依賴於全局值的替代方法。 其背后的邏輯是,當Promise返回一個值時,該值可用於傳遞給'then'鏈接函數的函數。 在這種情況下,當我們使用Promise.all時,Promise.all將一個Promise返回值的列表傳遞給它的'then'函數。 因此,我們可以將returnValues參數的元素加在一起以計算總計。

使用for..of循環而不是forEach,其中等待應按預期工作

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}`);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM