【问题标题】:Scope of variables and modules in Node.Js modules leading to RangeError: Maximum call stack size exceeded导致 RangeError 的 Node.Js 模块中的变量和模块范围:超出最大调用堆栈大小
【发布时间】:2020-12-16 12:34:02
【问题描述】:

我遇到了一个奇怪的问题,即多次启动外部模块在几次迭代后出现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。所以我试图了解在模块/导出函数中我应该在哪里声明它们以获得最大效率。

【问题讨论】:

    标签: javascript node.js scope node-modules


    【解决方案1】:

    将当前的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 找到关于此的出色、彻底的讨论。如果没有其他代码示例,则无法提供更多详细信息,因为此答案的最早部分涉及您提供的特定案例。

    【讨论】:

    • 当然,这是一种方法,但我的问题是关于 Node.Js 中模块的使用更笼统
    • 在这种情况下,您可能需要改写您的原始帖子,因为您直接提出的问题就是上面回答的问题。既然你已经澄清了,我会更新我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 2021-09-21
    • 2014-12-03
    • 2018-02-06
    相关资源
    最近更新 更多