问题描述
我遇到了一个奇怪的问题,外部模块多次启动,经过几次迭代后出现RangeError: Maximum call stack size exceeded
错误。
我将使用简单的构造演示导致此错误的原因。问题是如何使这种构造更有效,以使特定变量不会使内存过载。
假设我有一个名为validate
的模块。为了简单起见,让我们假设elem
不是外部模块,而是实际上是一个变量:
// validate.js
var elem = 0;
exports.testRun = function() {
elem++
console.log(elem)
}
,如果我从应用程序的另一个位置(从run.js
启动):
// run.js
var validate = require('validate')
for (let i = 0; i < 5; i++) {
validate.testRun()
}
输出将是:
1
2
3
4
5
有道理。
但是,现在假设我将run.js
放入模块中并从应用程序的另一个位置运行它–出于某种原因,我的变量增加了,我不明白:
// validate.js
var elem = 0;
exports.testRun = function() {
elem++
console.log(elem)
}
// end of validate.js
// run.js
var validate = require('validate')
exports.otherRun = function () {
for (let i = 0; i < 5; i++) {
validate.testRun()
}
}
// end of run.js
// new.js
var otherone = require('./run')
for (let i = 0; i < 5; i++) {
otherone.otherRun()
}
// end of new.js
输出为:
1
2
3
...
25
这也是有道理的,因为该变量是在全局范围内定义的,实际上需要一次,然后重复。
但是,现在有个问题:声明此变量(不在模块之间发送)最有效的方法是什么,以便每次启动new.js
中的循环时都将其重置?输出将是1234512345
等。
之所以这样问,是因为我在外部模块中遇到了一些需要声明为变量的问题,并且在处理循环时我发现它们会遇到RangeError: Maximum call stack size exceeded
。因此,我试图了解应该在模块/导出函数中的哪个位置声明它们,以实现最大效率。
解决方法
将当前的for
循环索引传递到testRun
中,如果它是0
,则将elem
设置为等于0
。我通常也建议从var
切换到let
。见下文:
// validate.js
let elem
exports.testRun = function(i) {
if (i === 0) {
elem = 0
} else {
elem++
}
console.log(elem)
}
// run.js
let validate = require('validate')
exports.otherRun = function () {
for (let i = 0; i < 5; i++) {
validate.testRun(i)
}
}
Maximum call stack size exceeded
错误很可能是递归的结果,而不是循环本身,尽管无限运行的while
循环也可能导致这种情况。 (因此,我尽可能地使用for
循环。)here可能是关于此的极好的,详尽的讨论。如果没有其他代码示例,则无法提供更多详细信息,因为此答案的最早部分是针对您提供的具体情况的。