Node.Js模块中导致RangeError的变量和模块的范围:超出最大调用堆栈大小

问题描述

我遇到了一个奇怪的问题,外部模块多次启动,经过几次迭代后出现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可能是关于此的极好的,详尽的讨论。如果没有其他代码示例,则无法提供更多详细信息,因为此答案的最早部分是针对您提供的具体情况的。