Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous Javascript Recursion

I'm not sure how to ask the question rattling around in my head right now, so bear with me. I'm brand new to asynchronous programming, and I figured the best way to learn would be to make a little javascript pong game. I started with a shootball() function and just bounce a div around another div. How I did this was with something like this:

function shootball(angle, speed){
    angle = (angle/360.0)*2*Math.PI;
    var ballmotion = setInterval(function(){
        var nowx, nowy, minusY, plusX;
        nowx = $("#ball").position().left;
        nowy = $("#ball").position().top;
        minusY = Math.sin(angle) * 4.0;
        plusX = Math.cos(angle) * 4.0;
        if(hitsWall(nowx+plusX, nowy-minusY)){
            clearInterval(ballMotion);
            shootball(newAngle(nowx+plusX, nowy-minusY), speed);
        }
        $("#ball").css("left", (nowx + plusX)).css("top", (nowy - minusY));
     }, 10/speed);
}

I'm not a big fan of big unnecessary recursion, but I just wanted to try it out. Lo and behold it works exactly as I would expect. But as I started fleshing out the rest of the program, it occurred to me that I had no way of avoiding this recursive nature. So my question: Does javascript somehow recognize that the calling "shootball" function is essentially finished after calling clearInterval? Or does this really find itself loading up my stack with unnecessary activation records? Thanks in advance for any expertise this may drum up.

like image 638
Ryan Avatar asked Oct 04 '22 20:10

Ryan


1 Answers

Does javascript somehow recognize that the calling "shootball" function is essentially finished after calling clearInterval?

No, shootball was finished long ago, right after the assignment to ballmotion. However, its variable scope (angle, speed, ballmotion and the parent scope) did persist since the anonymous function built a closure with it and was referenced from outside (from the scheduler). And that scope will get garbage collected after the clearInterval call which removed the references to it.

does this really find itself loading up my stack with unnecessary activation records?

No. Every function that is executed via setTimeout/setInterval runs in its own execution context, with a brand new call stack.

like image 101
Bergi Avatar answered Oct 26 '22 10:10

Bergi