длительные обратные вызовы времени ожидания не позволяют выполнять обратные вызовы requestAnimationFrame - PullRequest
0 голосов
/ 07 сентября 2018

Я смотрел Джейк Арчибальд, рассказывающий о цикле событий , и узнал, что в браузере есть 3 очереди:

  • очередь вызовов
  • очередь микрозадач
  • очередь анимации

, которые ведут себя по-разному, когда дело доходит до выполнения своих предметов.

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

Очередь Microtask выполняет свои элементы до тех пор, пока очередь не станет пустой (что может привести к бесконечной блокировке)

Очередь анимации предназначена для requestAnimationFrame обратных вызовов, и она также выполняет свои элементы до тех пор, пока очередь не станет пустой, за исключением обратных вызовов, которые были добавлены в один из выполняемых в данный момент обратных вызовов (те, которые выполняются в следующем кадре).

Я хотел проверить это и создал скрипт, который рекурсивно вызывал requestAnimationFrame и поставил в очередь 50 обратных вызовов с тайм-аутом, которые блокировали основной поток на 15 мс.

for (let i = 0; i < 50; i++) {
  setTimeout(() => {
    block(15);
    console.log(`timeout ${i}`)
  })
}

const startDate = Date.now();
function raf() {
  requestAnimationFrame((x) => {
    if (Date.now() < startDate + 1000) {
      console.log(`raf ${x}`)
      raf();
    }
  })
}

raf();



function block(ms) {
  const startDate = Date.now();
  while (Date.now() < startDate + ms) { }
}

живая демоверсия: https://stackblitz.com/edit/js-xdpbbb?file=index.js

Поскольку время блока примерно равно времени между кадрами (60 кадр / с дает 16,666 мс), я ожидал переплетения между обратными вызовами raf и timeout. Но результат был совершенно другим:

results

Как вы можете видеть, между обратными вызовами raf существует примерно 10 тайм-аутов, для завершения которых требуется около 150 мс. Почему это не так:

  1. Тайм-аут CB
  2. анимация, кб
  3. тайм-аут cb
  4. анимация cb
...