我一直在使用setTimeout(function(){ ... }, 0)
作为将函数调用延迟一个tick的方法。
通常情况下,当我尝试直接操作事件循环以确保事物按特定顺序执行时,我一直在使用此方法,并且在大多数情况下,它与UI有关。
有时我会感觉到“滴答”,特别是当我使用它来运行元素上的第三方JS库时。
但我最近发现requestAnimationFrame
。这几乎达到了同样的目的,但是更加优雅。
现在我很好奇,是否有任何案例,使用setTimeout(function(){ ... }, 0)
比requestAnimationFrame(function(){ ... })
更有利?
答案 0 :(得分:1)
来自https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
我看到的只有红旗是这个人:
运行时,回拨率可能会降低到较低的比率 背景标签或隐藏的iframe,以提高效果 和电池寿命。
但我相信只有当你有requestAnimationFrame以递归方式调用自身时才会发生。
因此,如果您有一些使用requestAnimationFrame的长时间运行代码,如果用户不在该选项卡上,则可能需要更长时间。除此之外,你正在使用一个函数来做一些从未打算做的事情,但是setTimeout并没有被设计成一种跳过勾号的方法......
作为建议: 一般来说,我发现你通常可以通过正确使用promises等来避免setTimeout技巧。但我找到了案例,尤其是。当使用Angular 1.x时我无法找到比使用它更好的解决方案。
有趣的花絮。通过简单的性能测试,requestAnimationFrame似乎要快得多:
console.time()
for(let i = 0; i < 100000; i++){
requestAnimationFrame(() => {(5*5*77/3)*88});
}
console.timeEnd()
得到~80ms(在我的电脑上)
console.time()
for(let i = 0; i < 100000; i++){
setTimeout(() => {(5*5*77/3)*88}, 0);
}
console.timeEnd()
得到~225ms(在我的电脑上)
答案 1 :(得分:1)
他们不是一回事。
使用setTimeout(fn, 0)
调用自身的函数将尽可能多地运行。
使用requestAnimationFrame(fn)
调用自身的函数将每帧调用一次 - 通常每秒60次。顾名思义,它适用于动画,在这种情况下,更新页面状态比显示它更有意义。
答案 2 :(得分:0)
视情况而定,某些情况下,例如动画requestAnimationFrame
更好,而某些情况下,例如实时处理,我更喜欢setTimeout 0
。
为什么?因为requestAnimationFrame
就像setTimeout(func, 1000/60)
,所以setTimeout 0
更快。
但是如果您比较requestAnimationFrame
与setTimeout(func, 1000/60)
。 requestAnimationFrame
比setTimeout
更精确。