Почему этот код работает?
Вот какая я думаю, почему он работает:
1) Переменные все сохраняются и срабатывает вызов функции gameEngineStart(gameLoopRight)
2) Выполняются тело функции gameEngineStart
->
gameEngine
= телу функции gameLoopRight
, потом срабытывает вызов функции gameEngineStep()
3) Выполняется функция gameEngineStep
->
вызывается reqAnimFrame(gameEngineStep)
, reqAnimFrame
становится ссылкой на функцию requestAnimationFrame
, если всё хорошо, иначе возвращается название функции для нужного браузера, а потом уже обычный setTimeout
reqAnimFrame
вызывается с аргументом gameEngineStep
, который должен был вызвать саму себя(по логике) и так бесконечно. Но дальше происходит срабатывание gameEngine()
Дальше всё понятно как работает, но вот этот момент непонятен, почему функция не вызывает саму себя бесконечно, а может выполнить вызов gameEngine()
?
var gameEngine;
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var x = 10, y = 10;
function drawRect() {
context.fillStyle = 'black';
context.clearRect(0, 0, 300, 300);
context.fillRect(x, y, 50, 50);
}
var reqAnimFrame = (function() {
return requestAnimationFrame ||
mozRequestAnimationFrame ||
webkitRequestAnimationFrame ||
oRequestAnimationFrame ||
msRequestAnimationFrame ||
function (callback) {
setTimeout(callback, 1000 / 60);
}
})();
function gameEngineStart(callback) {
gameEngine = callback;
gameEngineStep();
}
function gameEngineStep() {
reqAnimFrame(gameEngineStep);
gameEngine();
}
function setGameEngine(callback) {
gameEngine = callback;
}
function gameLoopRight() {
drawRect();
x += 2;
if (x >= 240) {
setGameEngine(gameLoopLeft);
}
}
function gameLoopLeft() {
drawRect();
x -= 2;
if (x < 20) {
setGameEngine(gameLoopRight);
}
}
gameEngineStart(gameLoopRight);
#canvas {
border: 1px solid black;
}
<canvas id="canvas" width="300px" height="70px"></canvas>
Я точно не понял полностью как работает requestAnimationFrame
, но при выводе в консоль сообщения из функции gameEngineStep
, оно выводилось 60 раз в секунду. Я пытался тоже самое проделать(вызвать саму себя функцией, без таймеров), но без requestAnimationFrame
, в итоге всё глючило и браузер не отвечал.
requestAnimationFrame
работает так, что она не нагрузит процессор, если вызывать функцию рекурсивно, она будет вызываться только 60 раз в секудну(обычно, зависит от монитора).
Мне не нравится, что requestAnimationFrame
(я так думаю, возможно это неправильно) срабатывает больше раз, чем необходимо для отрисовки, т.е. некоторые вызовы функции происходят просто так. В будущем планирую разобраться, как это работает, когда пойму
примерно ваша цитата: а потом уже обычный таймаут с вечным циклом.
как работает таймаут? вызывается, запоминает что ему ныжно выпольнить что-то там черзе какое то время. и все. вышел из функции. и пошел работать код дальше:
function gameEngineStep() {
reqAnimFrame(gameEngineStep);
gameEngine();
}
а дальше - gameEngine() Вот, а когда пройдет положенное время внезапно в параллельном процессе исполнится то что запомнил сетТаймаут. В параллельном! И помните, каждый вызов сетТаймаут дает именно параллельный процесс.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Понимаю как нелепо может выглядеть этот вопрос,и как криво я описал проблему,но я новичок в этом деле,так что сорре
Эта функция вызывается по нажатию на кнопку:
В расширении Google Chrome, установлено событие, которое отслеживает загрузку определенной страницы сайта exemplecom: