[英]Scope of variables and modules in Node.Js modules leading to RangeError: Maximum call stack size exceeded
I experienced a strange problem with external modules being launched several times arriving to the RangeError: Maximum call stack size exceeded
error after a few iterations.我遇到了一个奇怪的问题,外部模块被多次启动,到达
RangeError: Maximum call stack size exceeded
错误几次迭代后。
I will demonstrate what leads to this error using a simple construct.我将使用一个简单的构造来演示导致此错误的原因。 The question is how this construct can be made more efficient so that a particular variable does not overload the memory.
问题是如何使这种构造更有效,以便特定变量不会使内存过载。
Suppose I have a module called validate
.假设我有一个名为
validate
的模块。 Let's imagine that elem
is not an external module but actually a variable, for simplicity sake:为简单起见,让我们假设
elem
不是外部模块,而是实际上是一个变量:
// validate.js
var elem = 0;
exports.testRun = function() {
elem++
console.log(elem)
}
and if I launch it from another place in my app (from run.js
):如果我从应用程序的另一个位置(从
run.js
)启动它:
// run.js
var validate = require('validate')
for (let i = 0; i < 5; i++) {
validate.testRun()
}
The output will be:输出将是:
1
2
3
4
5
Which makes sense.这是有道理的。
However, now imagine I make run.js
into a module and run it from another place in the app — in that case for some reason my variable gets incremented, which I don't understand:但是,现在想象我将
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
The output is:输出是:
1
2
3
...
25
Which also makes sense, because the variable is defined in the global scope and is actually required once and then reiterated.这也是有道理的,因为变量是在全局范围内定义的,实际上需要一次然后再重复。
However, now a question: what would be the most efficient way to declare this variable (without sending it between the modules) so that it would get reset every time the loop in the new.js
is launched?但是,现在有一个问题:声明这个变量(而不在模块之间发送它)的最有效方法是什么,以便每次启动
new.js
的循环时它都会被重置? The output would then be 1234512345
etc.输出将是
1234512345
等。
I'm asking this because I encountered some problems with external modules that need to be declared as variables and when dealing with loops I discovered that they would run into RangeError: Maximum call stack size exceeded
.我问这个是因为我遇到了一些需要声明为变量的外部模块的问题,并且在处理循环时我发现它们会遇到
RangeError: Maximum call stack size exceeded
。 So I'm trying to understand where in the module / export function I should declare them for maximum efficiency.所以我试图了解我应该在模块/导出函数中的哪个位置声明它们以获得最大效率。
Pass the current for
loop index into testRun
, and if it is 0
, set elem
equal to 0
.将当前的
for
循环索引传递给testRun
,如果它是0
,则将elem
设置elem
等于0
。 I also generally advise switching from var
to let
.我通常也建议从
var
切换到let
。 See below:见下文:
// 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)
}
}
A Maximum call stack size exceeded
error is likely to be a result of recursion, not a loop per se, although a while
loop running infinitely can cause this as well. Maximum call stack size exceeded
错误可能是递归的结果,而不是循环本身,尽管无限运行的while
循环也会导致这种情况。 (For that reason I use for
loops whenever possible.) An excellent, thorough discussion about this may be found here . (出于这个原因,我尽可能使用
for
循环。)可以在此处找到有关此问题的出色而彻底的讨论。 It is not possible to give further detail without additional code examples, as the earliest part of this answer addresses the specific case you provide.如果没有其他代码示例,则无法提供更多详细信息,因为本答案的最早部分针对您提供的特定案例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.