skip to Main Content

I need a function to print numbers from 1 to 10 every ms using recursion.
My function prints numbers ​​from 2 to infinity, probably, although the condition for exiting the recursion is written. What am I doing wrong?

 function printNumbers2(from, to) {
  let number = from;

  if (number == to) {
    return number;
  } else {
    return setTimeout(() => {
      console.log(number);
      number++;
      printNumbers2(number);
    }, 1000);
  }
}

console.log(printNumbers2(1, 10));

Result:

Timeout {
  _idleTimeout: 1000,
  _idlePrev: [TimersList],
  _idleNext: [TimersList],
  _idleStart: 15,
  _onTimeout: [Function (anonymous)],
  _timerArgs: undefined,
  _repeat: null,
  _destroyed: false,
  [Symbol(refed)]: true,
  [Symbol(kHasPrimitive)]: false,
  [Symbol(asyncId)]: 2,
  [Symbol(triggerId)]: 1
}
1
2
3
4
5
6
7
8
9
10
11
12
13

3

Answers


  1. You forgot to pass in your "to" parameter in your recursive call:

    function printNumbers2(from, to) {
      let number = from;
    
      if (number == to) {
        return number;
      } else {
        return setTimeout(() => {
          console.log(number);
          number++;
          printNumbers2(number, to); // <-- pass in your "to" parameter
        }, 1000);
      }
    }
    
    console.log(printNumbers2(1, 10));
    
    Login or Signup to reply.
  2. That’s not how javascript works.

    The use of setTimeout in a recursive manner can lead to multiple setTimeout calls being queued up, potentially causing a timeout error due to excessive function calls without breaks.

    Corrected code:

    function printNumbers2(from, to) {
      let number = from;
    
      function printNext() {
        console.log(number);
        number++;
    
        if (number <= to) {
          setTimeout(printNext, 1000); // Schedule next execution
        }
      }
    
      printNext(); 
    }
    
    printNumbers2(1, 10); 
    
    Login or Signup to reply.
  3. As Julien Rheinbach noted you forgot to pass to in the timed call, so number == to will never occur.

    FYI, your code can be simplified. Here is a cleaned up version, adding a time variable to make varying the timeout value possible.

    printNumbersTimed(1, 10);
    
    function printNumbersTimed(from, to, time = 0.5) {
      const isDone = from === to;
      console.log(isDone ?
        `all done, your number is ${from}` :
        `now at: ${from}`);
    
      return isDone || 
        setTimeout(() =>
          printNumbersTimed(from + 1, to, time), time * 1000);
    }
    .as-console-wrapper {
      max-height: 100% !important;
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search