背景:
使用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
(因为它们将共享一个frameId)一起使用
答案 0 :(得分: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,现在我们正在请求一个新的animationframe,该ID为51。这一次,尽管我们的if条件为true,所以取消了对id 51的请求。调用回调函数后,对ID 50的请求已完成,因此无需取消它。