是requestAnimationFrame实现's递归
Is requestAnimationFrame implementation's recursive?
我目前正在试验three.js,它依赖于requestAnimationFrame
来执行动画。
在调用立方体旋转和renderer.render
函数之前,以下代码不会导致无限递归吗?
function render() {
requestAnimationFrame(render);
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
}
render();
代码是有效的,但我正在努力提高我对JavaScript的整体理解。
在我看来,render是作为回调函数调用的。但这是否意味着JavaScript在停止执行下一个调用之前继续运行函数中的代码?
这只要求浏览器在下一个渲染循环之前调用回调:
只要准备好在屏幕上更新动画,就应该调用此方法。这将要求在浏览器执行下一次重新绘制之前调用动画函数。
所以这里没有递归,函数继续执行。
您也可以使用cancelAnimationFrame
取消回调请求。
看这里。
不,堆栈不会爆炸,因为requestAnimationFrame
的回调是异步执行的。在清除整个调用堆栈之前,异步代码永远不会运行。有关事件循环的说明,请参阅此视频。
考虑这个演示来说明:
const fakeRAF = cb => setTimeout(cb, 1000 / 60);
(function rerender() {
fakeRAF(rerender);
console.log(performance.now());
})();
你可以让它运行一整天。当然,requestAnimationFrame
比fakeRAF
做的工作多得多,因为它在计算何时触发cb
方面非常聪明,但这个简单的演示足以证明它不是递归的,这要归功于setTimeout
提供了异步API。
顺便说一下,在函数的顶部还是底部调用requestAnimationFrame
或fakeRAF
并不重要。函数中的所有同步代码都必须在触发回调之前运行,这样就不会出现下一帧踩在上一帧上或类似的问题。
在第一次render()调用之后,RequestAnimationFrame将异步处理渲染函数,每秒调用它约60次。您的函数不是递归的,因为Javascript将继续执行代码。
但是,您应该只在渲染函数的最后使用RequestAnimationFrame,作为函数的最后一个命令。想象一下,你有一个大场景,有很多动画:在完成参数更新之前请求下一帧,可能会造成巨大的混乱。
您也可以使用setTimeout来处理动画,调用具有所需帧速率的渲染方法,如下所示:
var desideredFrameRate = 60;
window.myRequestAnimationFrame = function(callback) {
setTimeout(callback, 1000/desiredFrameRate);
}
- 数组在递归方法中设置为null
- Kendo:我该如何在树视图中创建一个递归的hieiarchy
- 递归使用 eval() 是检查程序执行的好方法吗?
- 使用递归、Ramda.js和无点样式重构字符串的getPermutations()
- 递归深度比较
- Eloquent JavaScript递归示例如何终止为返回1,但仍然输出指数值
- 递归函数中断
- 如何递归地获取嵌套对象中所有子对象的列表
- JavaScript 素数搜索无限递归
- 在递归生成器函数中,yield后面的*(星号/星号)语法意味着什么
- 递归|两个函数名
- 有没有一种方法可以在Javascript中进行可变递归currying
- 如何对不同的表递归使用以下代码
- 将jQuery对象传递到setTimeout递归函数中
- 有更好的方法吗?(递归解析HTML unicode实体)
- 为什么递归生成器函数没有't在ES2015工作
- 使用递归实现加性持久性
- 递归显示n元树
- 无递归的异步循环
- php中的脚本重定向是递归的