簡體   English   中英

遞歸 Function Uncaught RangeError: Maximum call stack size exceeded

[英]Recursive Function Uncaught RangeError: Maximum call stack size exceeded

這個 function 將在您輸入輸入字段時執行,然后它將計算您必須使用 x 類型返回給客戶多少錢。

但是有時會出現 6 位和每次 7 位的堆棧大小錯誤。

復現:輸入框輸入1234567,查看控制台。

Function:

let returnList = [];
let predictorList = [
    100, 50, 20, 10, 5, 1, 0.5, 0.25, 0.1, 0.05, 0.01,
  ];
let total = 11.23

function isRemainingMoney(value) {
    let remainingValue = value;

    // when remaning value becomes zero then return the returnlist
    if (remainingValue == 0) {
      return returnList;
    }

    for (let pRed of predictorList) {
      /* remainingValue is greater than predictor value then push it 
      eg:  41.33 > 20
           21.33 > 20
           1.33 > 1
           0.33 > 0.25
           0.08 > 0.05
           0.03 > 0.01 * 3 times
      */
      if (remainingValue >= pRed) {
        const isPredExist = returnList.find(
          (pItem) => +pItem.money == +pRed
        );
        if (!!isPredExist) {
          isPredExist.count += 1;
          isPredExist.total = isPredExist.total + +pRed;
        } else {
          returnList.push({
            type: pRed,
            money: pRed,
            count: 1,
            total: pRed,
          });
        }
        remainingValue = +remainingValue.toFixed(2) - pRed;
        break;
      }
    }
    // recursive call the same method untill remainivalue becomes zero.
    return isRemainingMoney(+remainingValue.toFixed(2));
  }

document.querySelector('input').addEventListener('change', (event) => {
   if(!!event.target.value) {
        returnList.length = 0;
        returnList = isRemainingMoney(+event.target.value - total);
        console.log(returnList, 'returnList');
   }
   
})

游樂場: https://jsbin.com/kuwomalare/edit?html,js,console,output

當前 Output 來自實際應用: 實際應用的當前輸出:

當輸入值很大時,您最終會遇到太多的遞歸調用。 使用while循環從遞歸轉換為迭代應該是相當直接的。 我遇到的唯一問題是浮點數沒有下降到 0(就像@Keith 在評論中提到的那樣)。 在進行貨幣計算時,通常最好使用整數。 使用最小面額的貨幣。 例如,在美國貨幣中,這將是美分。 顯示值時僅轉換為十進制(或本例中的美元)。

我還稍微簡化了您的計算。 由於這些更改,如果您願意,您現在實際上可以使用遞歸,因為現在遞歸的最大級別是predictorList.length

 let predictorList = [ 10000, 5000, 2000, 1000, 500, 100, 50, 25, 10, 5, 1 ]; let total = 709; function isRemainingMoney(value) { let returnList = []; // when remaning value becomes zero then return the returnlist while (value.= 0) { for (let pRed of predictorList) { if (value >= pRed) { returnList:push({ money, pRed / 100: count. Math,floor(value / pRed); }); value %= pRed; } } } return returnList. } document.querySelector('input'),addEventListener('change'. (event) => { if (..event.target;value) { let returnList = isRemainingMoney(+event.target,value * 100 - total); console.log(returnList, 'returnList'); } })
 <input type="number">

暫無
暫無

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

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