javascript - 当 ids 不断增加时,cancelAnimationFrame 如何工作?

标签 javascript settimeout setinterval requestanimationframe cancelanimationframe

背景:

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

setInterval/setTimeout:

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

请求动画帧: 使用 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一起工作(因为它们将共享一个frameId)

最佳答案

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

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 条件为 true,所以它取消了对 id 51 的请求。由于调用了回调函数,id 50的请求已经完成,无需取消。

关于javascript - 当 ids 不断增加时,cancelAnimationFrame 如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55909709/

相关文章:

javascript - 当用户决定在 onbeforeunload 事件后留下时执行操作

javascript - 如何让导航栏在缩放时消失?

javascript - 如何一次验证所有字段?

Javascript 定时器的顺序

javascript - 对象、它们的实例和 setTimeOut 效果

javascript - 动态设置超时

JavaScript:如何防止用户使 setInterval/setTimeout 事件崩溃?

javascript - 引用和调用对象问题?

javascript - 下拉列表以过滤特定列上的行

等待 GET 完成时的 Javascript setInterval