Можем ли мы считать requestAnimFrame «выходом» цикла приложения, позволяющим обрабатывать цикл событий?

StackOverflow https://stackoverflow.com//questions/21010396

Вопрос

я использую requestAnimFrame метод в JavaScript, чтобы обновить холст в основном цикле моей программы:

window.requestAnimFrame = (function(callback) {
  return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
    function(callback) {
      window.setTimeout(callback, 1000 / 60);
    };
})();


function animate() {
    requestAnimationFrame( animate );
//var runcount = 100;
//for (var i=0;i<=100;i++) {
    draw();
//    if (runcount === i)
//        alert("Completed program loop");
//    }
}

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

Тот факт, что холст не обновлялся до завершения моей программы, заставил меня подумать, что обновление холста выполняется в другом потоке, который не имеет приоритета.(Но мы знаем, что JavaScript является однопоточным).

Мой вопрос - Можем ли мы считать requestAnimFrame «выходом» цикла приложения, позволяющим обрабатывать цикл событий? Могу ли я по-прежнему считать, что JavaScript является однопоточным?

Это было полезно?

Решение

Вы не уточнили, как вы выполнили итерацию 1000 раз, но я предполагаю, что вы имеете в виду, что вы выполняли итерацию с использованием for или while петля (?поправьте меня если я ошибаюсь..).

Когда вы выполняете цикл for/ while, скрипт будет выполняться до тех пор, пока этот цикл (или область действия) не завершится.Поскольку JS, как вы знаете, является однопоточным, он не может обрабатывать такие вещи, как очередь событий, пока он это делает, поэтому ничто не сможет обновляться (включая.DOM) до тех пор, пока цикл не завершится (вообще говоря, может существовать специфичная для браузера реализация, которая разрешает обновления DOM, если обновления DOM запускаются, например, в отдельном потоке, но это отдельная вещь от JS).

Теперь, когда вы реализовали rAF, вы выполняете одну итерацию для каждого рамка.Это означает, что у браузера есть время обработать очередь событий. асинхронно (не то же самое, что многопоточный), если только код, который вы обрабатывали в цикле, также некоторое время не выполнял цикл занятости, что создало бы тот же сценарий, что и первый.

Вы могли бы использовать setTimeout также.Что раф делает иначе чем например setTimeout или setInterval заключается в том, что это эффективная низкоуровневая реализация механизма таймера, способного синхронизироваться с монитором. ВПУСТОЙ период (вертикальное гашение, которое видеокарта выполняет с помощью опции, называемой vsync) - что означает, простым словом, частоту обновления монитора (обычно 60 Гц).Это позволяет нам создавать плавную анимацию, поэтому она называется request*Animation*Frame, поскольку именно для этого она и создана.

JS все еще однопоточный?Да, это не изменится (единственный способ добиться многопоточности в JS — использовать Web Workers).

РАФ что-то меняет?Не в этой области — это более точная и производительная альтернатива setTimeout и он синхронизируется по-другому, но это все.Он будет страдать от тех же ограничений, что и setTimeout невозможность запуска, если область занята (следовательно, request* часть имени, которая не подразумевает никаких гарантий), но когда она сработает, она будет синхронизирована с частотой обновления монитора.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top