DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Randall
Randall

Posted on

Is this async function recursive?

Somewhat of a philosophical question perhaps. Is this async function recursive?

async function stuff() {
  await someAsyncOperation();
  stuff();
}
Enter fullscreen mode Exit fullscreen mode

While the function looks like it's calling itself, it isn't really calling itself. It actually returns to the event loop after the call to someAsyncOperation(), and then the rest of the code is called later from a different context after the asynchronous operation finishes. Unlike a traditional recursive function, this will never overflow the stack.

So is it recursive? I still refer to functions like this as recursive.

Top comments (7)

Collapse
 
peerreynders profile image
peerreynders • Edited on

It isn't a recursive function as it isn't calling itself (or being called via mutual recursion); the syntax sugar only makes it look that way.

Roughly:

function stuff() {
  return new Promise<void>(executor);

  // ---
  function executor(resolve: () => void, _reject: (reason?: Error) => void): void {
    // `someAsyncOperation()` is on the callstack
    // but `finish()` is only placed on the
    // microtask queue once
    // `someAsyncOperation()` resolves
    // When `finish()` starts the 
    // callstack is (practically) empty
    //
    someAsyncOperation().then(finish);

    // ---
    function finish() {
      stuff();
      resolve();
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

By the time you hit the .then() in executor() stuff() is done. The finish() portion is scheduled in a microtask, not called.

You could however argue that stuff() is recursively scheduled.


Collapse
 
hbgl profile image
hbgl

A recursive function needs a base case and a recursive step, both of which are missing here. Hence I would not consider this a recursive function.

Collapse
 
miketalbot profile image
Mike Talbot

The only way that isn't recursive is if something is optimising for "tail-recursion" otherwise it still needs a stack context irrespective of what calls the continuation.

Collapse
 
mcwolfmm profile image
mcwolfmm

yes, it is recursive. recursion has nothing to do with the stack. recursive invocation can even be in a different thread or process.

Collapse
 
bwca profile image
Volodymyr Yepishev

This one is superior for hanging tabs, because the natural process of getting killed by stack overflow doesn't apply to it, amazing!

Collapse
 
riad_hoque_e6ff7a307813ff profile image
Riad Hoque

Is the function calling itself over and over again? Then yes it’s recursion. Recursion doesn’t necessarily mean the stack has to overflow.

Collapse
 
mistval profile image
Randall Author

The function isn't calling itself, not really. Async/await syntactic sugar just makes it look that way.

πŸ€” Did you know?

Β 
🌚 You can turn on dark mode in Settings