1

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.

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. Let's imagine that elem is not an external module but actually a variable, for simplicity sake:

// 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
 
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:

// 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? The output would then be 1234512345 etc.

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. So I'm trying to understand where in the module / export function I should declare them for maximum efficiency.

Aerodynamika
  • 7,883
  • 16
  • 78
  • 137

1 Answers1

2

Pass the current for loop index into testRun, and if it is 0, set elem equal to 0. I also generally advise switching from var to 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. (For that reason I use for loops whenever possible.) An excellent, thorough discussion about this may be found here. 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.

223seneca
  • 1,136
  • 3
  • 19
  • 47
  • sure, this would be one way to do that, but my question was more general about the use of modules in Node.Js – Aerodynamika Aug 28 '20 at 11:44
  • In that case, you may want to rephrase your original post, because the question you directly pose is the one answered above. Since you've clarified, I'll update my answer. – 223seneca Aug 28 '20 at 11:55