我的问题是相当简单的。我只是不明白这种行为是在我的环境的NodeJS发生。
下面的代码不超过最大函数调用堆栈:
const loop = (i, maxI) => {
if (i === maxI) {
return;
}
if (i % 1000 === 0) {
console.log(i);
}
return loop(i + 1, maxI)
}
if (!module.parent) {
loop(0, 100000000000000000);
}
然而不知何故下面的代码不会吹堆起来?
const loop = (i, maxI) => {
if (i === maxI) {
return;
}
if (i % 10000 === 0) {
console.log(i);
}
return loop(i + 1, maxI)
}
if (!module.parent) {
loop(0, 100000000000000000);
}
即使这样吹堆件:
const loop = (i, maxI) => {
if (i === maxI) {
return;
}
return loop(i + 1, maxI)
}
if (!module.parent) {
loop(0, 100000000000000000);
}
我使用的NodeJS v10.15.1在Windows 10,我猜尾递归未优化的NodeJS但如何,不是一个特殊的情况导致函数调用堆栈炸毁?
这是因为JS有一个堆,其中,它会将给函数的调用,并有一个分配给该堆栈内存的限制。
你应该换你的递归函数调用到的setTimeout,setImmediate或process.nextTick功能给node.js的清除栈的机会。如果你不这样做,有许多循环没有任何真正的异步函数调用,或者如果你不等待回调,您的RangeError:超过最大调用堆栈大小将是不可避免的。
这就是说,现在在你的第一个代码,你正在做
i % 1000
这不是在你的第二个代码完成的操作相对较轻的操作
i % 10000
首届一段代码,因为堆栈是越来越解放出来的下一个呼叫排队的时间,但在第二一段代码,该处理器还在做操作,而调用就会堆积起来获取运行次数太多。第三部分的代码实际上是在很多很多次,但终因再次堆栈被堵塞返回错误。
请尝试,把一个日志语句在第三个代码和尝试。这将使你的东西更清晰。