开发者问题收集

未捕获的 RangeError:超出最大调用堆栈大小 - 为什么?/如何避免?

2021-06-19
9615

我使用的是常规 JavaScript。

正如标题所示,我遇到了 RangeError,但我真的不知道如何避免它。 真正的问题是我不应该遇到它,而且如果我刷新页面,有十分之一的机会(估计)不会抛出错误。

代码: (它是关于从数组中挑选随机对象)

我有一个这样的数组:

var array = ["item1", "item2", "item3", "item4"]

等等,实际上我有 5 个数组,总共包含大约 4000 个字符。 我使用一个函数来生成一个随机数:

 function getRandomNumber(start, range) {
     range = range + 1;
     return Math.floor( (Math.random() * (range - start) ) + start );
}

这个函数有效,我甚至在网络的帮助下改进了我最初的方法,使它看起来像现在这样。

所以我这样调用这个函数:

function getObjects() {
    var randomObject1 = array[getRandomNumber(1, array.length -1)]
    var randomObject2 = array[getRandomNumber(1, array.length -1)]
    var randomObject3 = array[getRandomNumber(1, array.length -1)]

    var drawnItems = [randomObject1, randomObject2, randomObject3]

    if(drawnItems.length != new Set(drawnItems).size) {
        getObjects()
    }
}

我需要每轮绘制多个对象,所以我像所示那样多次执行此操作。 我最终得到一个包含如上所示随机绘制项目的数组。

然后我使用此代码来确定绘制的项目是否可以存储在 Set 中,这并不重要,但却是一种检查是否有任何对象被绘制两次的便捷方法。 => 在最终输出中,我只能让每个对象出现一次。

我可以看到这一切都是如何有问题的,但我不明白为什么计算机会面临这个问题,而如果我刷新几次,我就不会。我想说的是,事实上,计算机尝试的次数比我必须刷新才能达到有效星座的次数要多。 为什么 PC 会遇到这个问题,即使它尝试的次数更多?

当我尝试从仅包含 4 个对象的数组中绘制 3 个对象时,第一次发生了这种情况。如果我从 100 多个对象的大数组中绘制,我永远不会遇到问题。

2个回答

这是一个递归问题。您的函数会一遍又一遍地调用自身,直到堆栈填满并导致显示的错误。

如果删除这些代码行,您将解决错误:

if(drawnItems.length != new Set(drawnItems).size) {
    getObjects()
}

您有理由使用 if 条件来执行递归吗?

编辑:

为了避免重复的值,您可以使用以下代码来删除递归:

//First object won't be duplicated, so we declare it directly
var randomObject1 = array[getRandomNumber(1, array.length -1)];

var randomObject2 = null, randomObject3 = null;

do {
    randomObject2 = array[getRandomNumber(1, array.length -1)];
} while (randomObject2 == randomObject1);

do {
    randomObject3 = array[getRandomNumber(1, array.length -1)];
} while (randomObject3 == randomObject1 || randomObject3 == randomObject2);

使用上述代码,您将不断为 randomObject2 和 randomObject3 生成随机值,而它们与另一个值相同。

Jorge C.M
2021-06-19

getObjects 函数中有一个无限循环

此部分:

//...
 if(drawnItems.length != new Set(drawnItems).size) {
      getObjects()
   }
//...

此函数无限次调用自身,直到达到限制。这就是您收到此错误的原因。尝试使用循环,也许会有所帮助。

此外,我还发现了一些对您有帮助的东西: 超出最大调用堆栈大小错误

Arda Ravel
2021-06-19