当id持续递增时,cancelAnimationFrame如何工作?

问题描述 投票:0回答:1

背景:

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

的setInterval / setTimeout的:

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

requestAnimationFrame:当使用raf时,对于步骤的每次迭代,我们重置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一起工作(因为它们将共享一个frameIds)

javascript settimeout setinterval requestanimationframe cancelanimationframe
1个回答
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已经完成,因此无需取消它。

© www.soinside.com 2019 - 2024. All rights reserved.