requestAnimationFrame внутри обещания

Может кто-нибудь объяснить, что делает эта функция? Я понимаю, как requestAnimationFrame выполняется перед отрисовкой и рендерингом внутри кадра, но я не совсем уверен, в чем польза от помещения его в промис.

function nextFrame() {
  return new Promise(requestAnimationFrame)
}

person Adam    schedule 03.04.2020    source источник
comment
Принятый ответ дает отличное объяснение механики. Я думаю, что одной большой мотивацией будет то, что вы можете написать await nextFrame(); внутри функции async, например. в начале цикла, который должен запускаться один раз за шаг анимации.   -  person Matthias Fripp    schedule 04.02.2021


Ответы (1)


Конструктор Promise принимает так называемый executor в качестве первого аргумента, который можно использовать для управления потоком выполнения обещания. Эта функция имеет два аргумента: resolve и reject — это функции, которые вы вызываете для разрешения или отклонения промиса.

const promise = new Promise(function executor(resolve, reject) {
   resolve();
   // reject();
});

Эта функция executor вызывается внутри автоматически, когда вы создаете новое обещание, используя new Promise(executor).

Затем requestAnimationFrame требуется обратный вызов, который будет запускается всякий раз, когда браузер готов выполнить код вашего фрейма.

requestAnimationFrame(function frameCallback(timestamp) {
    // ...frame code
});

Если вы попытаетесь наложить requestAnimationFrame(frameCallback) подпись поверх executor(resolve, reject) подписи, то

  • requestAnimationFrame — это executor функция
  • frameCallback это resolve функция

Чтобы собрать все вместе, используйте new Promise(requestAnimationFrame)

  1. Конструктор промисов внутренне вызывает исполнителя (в данном случае requestAnimationFrame). Поскольку requestAnimationFrame вызывается, браузер внутренне планирует его как запрос на анимацию.
  2. Когда браузер готов анимировать запрошенный кадр, он вызывает обратный вызов, предоставленный requestAnimationFrame. В нашем случае resolve служит обратным вызовом. Кроме того, resolve будет передано с меткой времени из requestAnimationFrame, т. е. обещание будет разрешено со значением метки времени.

Я предполагаю, что этот код можно использовать для Promise-ify requestAnimationFrame, сконструированное обещание будет разрешено, как только будет вызван обратный вызов requestAnimationFrame.

const promise = new Promise(requestAnimationFrame);
promise.then(function frameCallback(timestamp) => {
  // ... frame code
});
person Michael Radionov    schedule 03.04.2020