【问题标题】:How does cancelAnimationFrame work when the ids keeps incrementing?当 id 不断增加时,cancelAnimationFrame 是如何工作的?
【发布时间】:2019-04-29 19:31:13
【问题描述】:

背景:

使用 setInterval 或 setTimeout 时,我们会收到一个 Id 来取消/清除操作。

setInterval/setTimeout:

const timeoutId = setTimeout(() => {clearTimeout(timeoutId)}, 1000);
const intervalId = setInterval(() => {clearInterval(intervalId)}, 1000);

requestAnimationFrame: 使用 raf 时,对于 step 的每一次迭代,我们都会重置 rafId,并且我们只在最新的 rafId 上调用 cancelAnimationFrame?

let rafId;

function step(timestamp) {
  rafId = requestAnimationFrame(step);
  console.log(timestamp, rafId)
  if(timestamp >= 1000) {
    cancelAnimationFrame(rafId);
  }
}
rafId = requestAnimationFrame(step);

问题:rafId 不断更新时,cancelAnimationFrame 如何知道关闭所有先前对 requestAnimationFrame 的调用?

我猜测 cancelAnimationFrame 使用 frameId 并关闭它后面的所有内容。

如果是这样,它如何与多个 requestAnimationFrames 一起工作(因为它们将共享一个 frameId)

【问题讨论】:

    标签: javascript settimeout setinterval requestanimationframe cancelanimationframe


    【解决方案1】:

    requestAnimationFrame 返回的 id 确实会不断增加一,但这并不重要。要保持请求“有效”,您需要在回调中重新请求它。 让我们看看最后一次触发回调函数步骤时发生了什么:

    function step(timestamp) {
      console.log("before " + rafId);
      rafId = requestAnimationFrame(step);
      console.log("after " + rafId);
      if (timestamp >= 1000) {
        cancelAnimationFrame(rafId);
      }
    }
    rafId = requestAnimationFrame(step);
    

    如果您查看控制台中的最后两行,则类似于:

    50 岁之前

    51 岁以后

    这意味着上次回调返回的 id 是 50,现在我们正在请求一个新的动画帧,它获取 id 51。这一次虽然我们的 if 条件为真,所以它取消了对 id 51 的请求。 id 50 的请求已经完成,回调函数被调用,无需取消。

    【讨论】:

      猜你喜欢
      • 2019-02-22
      • 1970-01-01
      • 1970-01-01
      • 2018-04-17
      • 2016-09-05
      • 2011-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多