0

I want to create X amount of random objects (100 in this example) in NodeJS. These objects have random values plus I want them created at randomIntervals. In order to accomplish this I wrote code similiar to this:

i=0;

while (i < 100){
 randomNum1 = Math.floor(Math.random()*100);
 randomNum2 = Math.floor(Math.random()*100);
 randomIntervalTime = Math.floor(Math.random()*100);

 timeOutInterval = setTimeout(function(){
   return new SomeObject(randomNum1, randomNum2)}, randomIntervalTime);
 i++;
}

The issue is that the value aren't preserved for the callback and it will just generate 100 new objects with all the same values (the last values created in the loop)

I realize this is because of some issue with the way callbacks work that I don't totally grasp, but my question is how would someone accomplish this in Nodejs.

user1500053
  • 79
  • 2
  • 9
  • exact duplicate of [setTimeout in a for-loop and pass i as value](http://stackoverflow.com/questions/5226285/settimeout-in-a-for-loop-and-pass-i-as-value) and many others. – Bergi Nov 12 '12 at 19:33
  • Why not create the random values inside the timeout? It is like you create the 100 objects now all together and then spawn them randomly later – Bergi Nov 12 '12 at 19:35
  • That might work Bergi, actually putting the random functions into the timeout, but I was trying to avoid the code mess. – user1500053 Nov 12 '12 at 19:49
  • 1
    Please see this to get an explanation for what's happening in your code: http://stackoverflow.com/questions/3572480/please-explain-the-use-of-javascript-closures-in-loops/3572616#3572616 – slebetman Nov 12 '12 at 20:00

1 Answers1

1

The original code places 100 callbacks into the event queue. Then, as each one executes, it uses the values stored in randomNum1 and randomNum2. Note when the first callback starts running, the while loop has already completed and the values of randomNum1 and randomNum2 are no longer changing. This explains why your code uses the same values each time. The fix for this is easy - simply move the definitions for randomNum1 and randomNum2 inside the scope of the function creating the new objects like so:

var createNewObject = function() {
  var randomNum1 = Math.floor(Math.random()*100);
  var randomNum2 = Math.floor(Math.random()*100);
  return new SomeObject(randomNum1, randomNum2);
};

var i = 0;

while (i < 100) {
  var randomIntervalTime = Math.floor(Math.random()*100);
  setTimeout(createNewObject, randomIntervalTime);
  i++;
}
David Weldon
  • 63,632
  • 11
  • 148
  • 146
  • You misunderstand; I don't literally want an object with random values. I have an object in which those values matter, but for testing I want to create the objects with random values for its real values. – user1500053 Nov 12 '12 at 21:34
  • I didn't define a new constructor, I simply invoked your `SomeObject` constructor with properly scoped values. If that isn't what you want, you should probably rephrase your question. – David Weldon Nov 12 '12 at 21:46