skip to Main Content

Please see the below code.
I thought the ‘11111111’ line would never be executed but it is.
Can anyone please explain.

function outer() {
  function inner(dur) {
    console.log('in inner');

    setTimeout(() => {

      outer();
      console.log('11111111');

    }, dur);

  }
  console.log('in outer');
  inner(5000);
}

outer();

I expected an infinite loop. That happened.
But I never expected the ‘11111111’ to execute.

2

Answers


  1. outer and inner run to completion because that’s what functions do when you call them. If you want to wait for asynchronous values, you must await them. In the example below, you will NOT see the 11111111 line printed –

    async function outer() {
      function inner(dur) {
        return new Promise(() => { // ✅
          console.log('in inner')
          setTimeout(async () => {
            await outer() // ✅
            console.log('11111111')
          }, dur)
        })
      }
      console.log('in outer')
      await inner(2000)
    }
    
    outer()

    Depending how you’re thinking about it, you could move the Promise to the outer function. I think I like this more because it’s clear that the outer function will never resolve. ie, it’s infinte

    function outer() {
      return new Promise(async () => { // ✅
        async function inner(dur) {
          console.log('in inner')
          setTimeout(async () => {
            await outer() // ✅
            console.log('11111111')
          }, dur)
        }
        console.log('in outer')
        await inner(2000)
      })
    }
    
    outer()

    You should use NEITHER because both result in creating infinitely many promises that never resolve and cannot be garbage collected (memory leak). These examples only show how to prevent the code from flowing to the 11111111 output.

    Login or Signup to reply.
  2. setTimeout() is an asynchronous function. It schedules its callback function to be called later, then returns immediately without waiting for it. So anything after setTimeout() will be executed immediately, without waiting for the timeout.

    So inner() returns immediately after it’s called, and then outer() returns immediately. Sometime later (after dur milliseconds), the callback function is invoked. This isn’t really recursive, because outer() and inner() have already returned. It’s a new top-level call from the event loop.

    In the callback, we execute outer() again. As above, it calls inner() again, which calls setTimeout() and returns, and then it also returns. Then console.log('11111111') is executed. dur milliseconds later this all will be repeated.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search