Pure Mathm
Pure Mathm

Reputation: 35

Why the unexpected result showing the results?

function init(n) {
 console.log(n);
 setInterval(init.bind(this, ++n), 1000);
}

// init(0); // Works bad


function init2(n) {
 setInterval(function() {
 console.log(n++);
 }, 1000);
}

init2(0); // Works fine

The first is a recursive function with to a setInterval.

Why does the first function NOT work as "expected"? with "expected" I mean that every 1 second is shown n + 1

I have been told that it is because by calling itself, calls are multiplying more and more and overflowing memory.

This I have noticed, but I can not make the mental image of this, can someone explain it to me more detailed? My problem is that I thought that, when executing the function every 1 second, I assured myself that exactly that would happen, but no. Calls multiply and do not wait for 1000 ms.

My mental image of the flow is:

1 - Call init ()

2 - Show n and then add 1 to n

3 - With a setInterval, execute the init () function only if 1000 ms have 
passed.

4- 1 second passed ..

5- We return to step 1

Upvotes: 1

Views: 60

Answers (3)

raina77ow
raina77ow

Reputation: 106385

The first snippet is fine if you use setTimeout instead:

function init(n) {
  if (n > 10) return; // 10 is enough in the example code
  console.log(n);
  setTimeout(init.bind(this, ++n), 1000);
}

init(0); // Works good

See, in your original case each call of init() runs setInterval - in other words, sets up a different task repeated each 1 sec. But you clearly need a single interval (as in the second snippet) - just continued at each step.

Upvotes: 1

Scott Marcus
Scott Marcus

Reputation: 65808

The problem is that init.bind(this, ++n) returns a new function and that new function then returns a new function, and so on. There isn't just one init function running every second. So, there are new copies being created every second and they are, in turn, making more copies. There isn't just one init running by itself. The copies are getting "stacked" up.

Upvotes: -1

JJJ
JJJ

Reputation: 33163

  1. Call init() manually. The function starts an interval that triggers once every second.
  2. A second later, the interval triggers the first time and calls init() which starts another interval.
  3. Two seconds later (counting from the start) both intervals trigger and call init(). Both function calls start a new interval. There are now 4 intervals in total.
  4. Three seconds later the 4 intervals trigger and each start a new interval. There are now 8 intervals in total.

and so on until you run out of resources.

In init2() this doesn't happen because the interval never calls the function again and therefore there's ever only one interval running.

Upvotes: 3

Related Questions