2013-06-13 10 views
5

Non sono sicuro di come fare la domanda che mi frulla in testa in questo momento, quindi portami con me. Sono nuovo di zecca per la programmazione asincrona, e ho pensato che il modo migliore per imparare sarebbe quello di fare un piccolo gioco di javascript sul pong. Ho iniziato con una funzione shootball() e ho semplicemente rimbalzato un div attorno a un altro div. Come ho fatto è stato con qualcosa di simile:Ricorsione asincrona Javascript

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); 
} 

Io non sono un grande fan di grande ricorsione inutile, ma volevo solo provare. Ecco, funziona esattamente come mi aspetterei. Ma mentre iniziavo a dare corpo al resto del programma, mi venne in mente che non avevo modo di evitare questa natura ricorsiva. Quindi la mia domanda: javascript in qualche modo riconosce che la funzione "shootball" che chiama è sostanzialmente finita dopo aver chiamato clearInterval? O si trova davvero a caricare il mio stack con record di attivazione non necessari? Grazie in anticipo per qualsiasi esperienza che questo possa scatenare.

+2

È possibile impostare un punto di interruzione e dare un'occhiata al callstack;) –

+1

Se una funzione richiede più tempo dell'intervallo dell'intervallo, _setInterval_ può diventare sgradevole, prendere in considerazione l'utilizzo di _setTimeout_. Inoltre, sono sicuro che è possibile spostare la maggior parte della funzione all'esterno dell'espressione in modo che non venga creata una nuova istanza di funzione ogni volta. –

+0

Non ne sono del tutto sicuro, ma credo che ogni volta che la palla non colpisce il muro la pila viene svuotata. – aledujke

risposta

4

javascript in qualche modo riconosce che la funzione di chiamata "shootball" è sostanzialmente terminata dopo aver chiamato clearInterval?

No, shootball terminato molto tempo fa, subito dopo l'assegnazione a ballmotion. Tuttavia, il suo ambito variabile (angle, speed, ballmotion e l'ambito genitore) persistono poiché la funzione anonima ha creato una chiusura con esso e ha fatto riferimento dall'esterno (dallo scheduler). E quell'ambito otterrà i dati raccolti dopo la chiamata clearInterval che ha rimosso i riferimenti.

questo si trova davvero a caricare il mio stack con record di attivazione non necessari?

No. Ogni funzione che viene eseguita tramite setTimeout/setInterval viene eseguito nel proprio contesto di esecuzione, con un nuovo stack di chiamate.

+0

Le variabili potrebbero non essere necessariamente cancellate poiché in alcuni browser manterranno tutte le variabili attive finché la pagina è in esecuzione. –

+0

@Derek: Vuoi dire che alcuni browser rovinano la garbage collection di 'clearInterval'? – Bergi

+0

Non sono sicuro, ma poiché non penso sia scritto negli standard, il browser non deve necessariamente cancellare variabili inutili. –