2013-06-13 2 views
5

Я не уверен, как задать вопрос, который сейчас грохочет в моей голове, так что несите меня. Я новичок в асинхронном программировании, и я решил, что лучший способ научиться - это создать небольшую игру для javascript-понга. Я начал с функции shootball() и просто подпрыгнул div вокруг другого div. Как я сделал это было что-то вроде этого:Asynchronous Javascript Recursion

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

Я не большой поклонник большой ненужной рекурсии, но я просто хотел попробовать его. Послушай, он работает точно так, как я ожидал. Но когда я начал контактировать с остальной частью программы, мне пришло в голову, что я не мог избежать этого рекурсивного характера. Итак, мой вопрос: как-то javascript признает, что вызывающая функция «стрелять» по существу заканчивается после вызова clearInterval? Или это действительно загружает мой стек ненужными активационными записями? Заранее благодарен за любую экспертизу, которая может быть запущена.

+2

Вы можете установить точку останова и посмотреть на столбец;) –

+1

Если функция требует больше времени, чем интервал, _setInterval_ может стать неприятным, вместо этого используйте _setTimeout_. Кроме того, я уверен, что вы можете переместить большую часть функции вне выражения, чтобы каждый экземпляр новой функции не создавался. –

+0

Я не совсем уверен, но я считаю, что всякий раз, когда мяч не врезался в стену, стек опустел. – aledujke

ответ

4

Является ли javascript каким-то признанием того, что вызывающая функция «стрелять» по существу закончена после вызова clearInterval?

No, shootball был закончен давно, сразу после назначения ballmotion. Тем не менее, его переменная область (angle, speed, ballmotion и родительская область) сохранялась, так как анонимная функция построила с ней закрытие и была указана извне (из планировщика). И эта область получит мусор, собранный после вызова clearInterval, который удалил ссылки на него.

действительно ли это загружает мой стек с ненужными активационными записями?

No. Каждая функцию, которая выполняется с помощью setTimeout/setInterval работает в своем собственном контексте исполнения, с совершенно новым стеком вызовов.

+0

Переменные могут не обязательно очищаться, так как в некоторых браузерах они будут поддерживать все переменные до тех пор, пока страница будет запущена. –

+0

@Derek: Вы имеете в виду, что некоторые браузеры завинчивают сборку мусора 'clearInterval'? – Bergi

+0

Я не уверен, но так как я не думаю, что это написано в стандартах, поэтому браузеру необязательно нужно очищать бесполезные переменные. –