Preguntas de entrevista de cinco minutos: la diferencia entre requestAnimationFrame y setTimeout

prefacio

Con respecto al estado actual de la comunidad técnica, analizo los retratos de los usuarios y creo que la mayoría de los usuarios prefieren artículos breves y rápidos, por lo que trato de desenterrar preguntas simples para entrevistas en el menor tiempo posible, y organizar y compartir el conocimiento detrás. ellos. Me gusta ayudarlo en el proceso de la entrevista de seguimiento. Si sucede que es su propio área ciega de conocimiento, es posible que desee apoyarlo

antecedentes

Creo que la mayoría de los desarrolladores han usado setTimeoutesta API. Si no, puedes usar la dirección de salto setTimeout . Pero creo que muchos desarrolladores nunca han usado requestAnimationFrameesta API, porque casi no necesitamos usarla en nuestro desarrollo habitual. Creo que también hay los amigos están ahí React.

Presentemos las dos API por separado. Antes de comenzar, también podríamos aprender a usarlas.requestAnimationFrame

requestAnimationFrame

Gu Mingsi, Request, Animation, Frame, Solicitud para hacer algo en el cuadro de animación, vea el artículo de ciencia popular para más detalles

window.requestAnimationFrame() Dígale al navegador que desea realizar una animación y pídale que llame a la función de devolución de llamada especificada para actualizar la animación antes del próximo repintado. Este método necesita pasar una función de devolución de llamada como parámetro, la función de devolución de llamada se ejecutará antes del próximo repintado del navegador.

gramática

window.requestAnimationFrame(callback);
复制代码

uso

Generalmente se usa para manipular cuadros de animación, cuando el objeto necesita realizar una animación antes de que se represente un cuadro. Por lo general, es mejor optimizar la animación en

const element = document.getElementById('some-element-you-want-to-animate'); // 需要移动的物体元素

let start;

function step(timestamp) {
  if (start === undefined) start = timestamp;
    
  const elapsed = timestamp - start;

  //这里使用`Math.min()`确保元素刚好停在200px的位置。
  element.style.transform = 'translateX(' + Math.min(0.1 * elapsed, 200) + 'px)'; // 每次移动 0.1 * elapsed 时间

  if (elapsed < 2000) { // 在两秒后停止动画
    window.requestAnimationFrame(step); 
  }
}

window.requestAnimationFrame(step); // 执行动画
复制代码

valor de retorno

Has leído bien, requestAnimationFramehay un valor de retorno.

Un  long número entero, el ID de solicitud, que es un identificador único en la lista de devolución de llamada. es un valor distinto de cero y no tiene otro significado. Puede pasar este valor window.cancelAnimationFrame() a función de cancelación de devolución de llamada.

cancelAnimationFrameEl parámetro de llamada es el ID devuelto cuando se llamó al window.requestAnimationFrame()método

establecer tiempo de espera

下面介绍的 setTimeout 相信大部分的开发者都使用过这个API吧,而且可以说相当熟悉

语法

var timeoutID = scope.setTimeout(function[ , delay, arg1, arg2, ...]);
var timeoutID = scope.setTimeout(function[, delay]);
var timeoutID = scope.setTimeout(code[, delay]);
复制代码

用法

用于延迟执行某个动作,或者可以循环调用自身,实现 setInterval 的效果,但注意需要释放 setTimeout 返回的 ID 利用clearTimeout 清空定时器。

var timeoutID;

function delayedAlert() {
  timeoutID = window.setTimeout(slowAlert, 2000);
}

function slowAlert() {
  alert('That was really slow!');
}

function clearAlert() {
  window.clearTimeout(timeoutID);
}
复制代码

返回值

返回值timeoutID是一个正整数,表示定时器的编号。这个值可以传递给clearTimeout()来取消该定时器。

这里有意思的点是 setTimeout()setInterval()共用一个编号池,技术上,clearTimeout()和 clearInterval() 可以互换。但是,为了避免混淆,不要混用取消定时函数。两者竟然是可以互换的

在同一个对象上(一个window或者worker),setTimeout()或者setInterval()在后续的调用不会重用同一个定时器编号。但是不同的对象使用独立的编号池。

两者对比

下面我们总结一下他们的差异

requestAnimationFrame setTimeout
语法 window.requestAnimationFrame(callback); setTimeout(callback, time)
用法 用于动画帧渲染时候,优化动画渲染场景中 用于延迟执行某个动作的场景中
返回值 正整数(用于后续 cancelAnimationFrame) 正整数 (用于后续 clearTimeout)
调用周期 0.2 ~ 0.3 ms (大约1帧的时间) 1 ~ 3 ms (setTimeout 第二个参数传入 0 情况下)

所以两者其实在时间上来理解的话,是在不同的调用周期中执行,setTimeout 是没有办法在 0.2 ~ 0.3 ms范围内执行某个回调的,这里我们提到时间范围的概念,这里就不得不提到 setTimeout 最小延迟时间的概念

setTimeout 最小延迟时间

console.time('ok')
setTimeout(() => {console.timeEnd('ok')}, 0); // ok: 1.93115234375 ms 预期是 0ms 实际上 大于 1ms
复制代码

Hay muchos factores que pueden hacer que la función de devolución de llamada de setTimeout se ejecute durante más tiempo que el valor esperado del conjunto.

La primera es la diferencia entre navegadores, en los navegadores setTimeout()/setInterval() el intervalo mínimo para cada invocación del temporizador es de 4ms, lo que suele ser causado por el anidamiento de funciones (el nivel de anidamiento alcanza cierta profundidad), o por la función setInterval ya ejecutada. está bloqueado. P.ej:

function cb() { f(); setTimeout(cb, 0); }
setTimeout(cb, 0);
复制代码
setInterval(f, 0);
复制代码

En Chrome y Firefox, la quinta invocación del temporizador está bloqueada; en Safari es la sexta; Edge es la tercera. Gecko  ha   adoptado este mecanismo desde la versión 56 ( ya implementado, consulte lo siguiente para obtener más detalles).setInterval()setTimeout()

Este retraso mínimo siempre ha sido diferente en diferentes navegadores (por ejemplo, Firefox): cuando se llama a setInterval() desde otro lugar, o cuando se llama a setTimeout() desde una función anidada (cuando el nivel de anidamiento alcanza una cierta profundidad), habrá un retardo de tiempo de espera.

Luego, el temporizador que implementa un retraso de 0 ms en el navegador debe usarse aquí window.postMessage, lo cual no se explica en esta introducción de contenido.

resumen

Este artículo termina aquí. Es probable que haya errores debido al nivel limitado. Bienvenido a hacer correcciones. Finalmente, espero que me puedan ayudar y me den pulgar arriba, esto es una gran afirmación y motivación para mi creación. espero que yo puedo ayudarle

Referencia del artículo

www.paulirish.com/2011/reques…
hacks.mozilla.org/2011/08/ani…
developer.mozilla.org/zh-CN/docs/…

Supongo que te gusta

Origin juejin.im/post/7078941440989986829
Recomendado
Clasificación