Is this recursion or not
Asked Answered
C

4

11
function x(){
  window.setTimeout(function(){
     foo();
     if(notDone()){ 
        x();
     };
  },1000);
}

My concern being unbounded stack growth. I think this is not recursion since the x() call in the timer results in a brand new set of stack frames based on a new dispatch in the JS engine.

But reading the code as an old-fashioned non JS guy it makes me feel uneasy

One extra side question, what happens if I scheduled something (based on math rather than a literal) that resulted in no delay. Would that execute in place or would it be in immediately executed async, or is that implementation defined

Custody answered 11/11, 2014 at 23:14 Comment(2)
Nope.. it sets timer and exists the function. The same when timer goes off - it sets a new timer and exists the function again.Handtohand
possible duplicate of why the funcion called by setTimeout has no callstack limit? or Asynchronous Javascript Recursion?Fridge
P
2

It is recusive in a sense that it is a function that calls itself but I believe you are right about the stack trace being gone. Under normal execution the stack will just show that it was invoked by setTimeout. The chrome debugger for example will allow you to keep stack traces on async execution, I am not sure how they are doing it but the engine can keep track of the stack somehow.

No matter how the literal is calculated the execution will still be async.

setTimeout(function(){console.log('timeout');}, 0);console.log('executing');

will output:

executing
undefined
timeout 
Plethora answered 11/11, 2014 at 23:27 Comment(2)
no, it's explicitly not a function that calls itself. It's a function that passes (but does not call) a closure that at some future point will be called from the JS event loop.Theall
It asynchronously calls itself but it still calls itself. I agree with everything else you are saying but I think we are arguing semantics here.Plethora
T
4

It's not - I call it "pseudo-recursion".

The rationale is that it kind of looks like recursion, except that the function always correctly terminates immediately, hence unwinding the stack. It's then the JS event loop that triggers the next invocation.

Theall answered 11/11, 2014 at 23:19 Comment(0)
P
2

It is recusive in a sense that it is a function that calls itself but I believe you are right about the stack trace being gone. Under normal execution the stack will just show that it was invoked by setTimeout. The chrome debugger for example will allow you to keep stack traces on async execution, I am not sure how they are doing it but the engine can keep track of the stack somehow.

No matter how the literal is calculated the execution will still be async.

setTimeout(function(){console.log('timeout');}, 0);console.log('executing');

will output:

executing
undefined
timeout 
Plethora answered 11/11, 2014 at 23:27 Comment(2)
no, it's explicitly not a function that calls itself. It's a function that passes (but does not call) a closure that at some future point will be called from the JS event loop.Theall
It asynchronously calls itself but it still calls itself. I agree with everything else you are saying but I think we are arguing semantics here.Plethora
A
1

One extra side question, what happens if I scheduled something (based on math rather than a literal) that resulted in no delay. Would that execute in place or would it be in immediately executed async, or is that implementation defined

Still asynchronous. It's just that the timer will be processed immediately once the function returns and the JavaScript engine can process events on the event loop.

Azriel answered 11/11, 2014 at 23:22 Comment(0)
D
0

Recursion has many different definitions, but if we define it as the willful (as opposed to bug-induced) use of a function that calls itself repeatedly in order to solve a programming problem (which seems to be a common one in a Javascript context), it absolutely is.

The real question is whether or not this could crash the browser. The answer is no in my experience...at least not on Firefox or Chrome. Whether good practice or not, what you've got there is a pretty common Javascript pattern, used in a lot of semi-real-time web applications. Notably, Twitter used to do something very similar to provide users with semi-real-time feed updates (I doubt they still do it now that they're using a Node server).

Also, out of curiously I ran your script with the schedule reset to run every 50ms, and have experienced no slowdowns.

Dwyer answered 3/1, 2015 at 23:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.