Recursive Function Uncaught RangeError: Maximum call stack size exceeded

Recursive Function Uncaught RangeError: Maximum call stack size exceeded

此函数将在您输入输入字段时执行,然后它将计算您需要 return 给客户多少钱 return。

但是有时 6 位和每次 7 位都会出现堆栈大小错误。

重现:输入框输入1234567,查看控制台

函数:

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

实际应用的当前输出: Current Output From real application:

当输入值很大时,您最终会进行过多的递归调用。它 应该 相当直接地使用 while 循环从递归转换为迭代。我 运行 遇到的唯一问题是浮点数没有下降到 0(如 中提到的)。在进行货币计算时,通常最好使用整数。使用最小面额的货币。例如,在美国货币中,这将是美分。显示值时仅转换为小数(或本例中的美元)。

我也稍微简化了你的计算。由于这些更改,如果你愿意,你现在实际上可以使用递归,因为现在递归的最大级别是 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">