requestAnimationFrame实现递归?

时间:2015-03-21 09:42:37

标签: javascript animation requestanimationframe

我目前正在尝试使用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继续运行 函数中的代码 停止继续下一次调用?

4 个答案:

答案 0 :(得分:4)

这只要求浏览器在下一个渲染循环之前调用你的回调:

  

只要您准备好在屏幕上更新动画,就应该调用此方法。这将请求在浏览器执行下一次重绘之前调用您的动画函数。

所以这里没有递归,你的函数继续执行。

您还可以使用cancelAnimationFrame取消回叫请求。

here

答案 1 :(得分:0)

requestanimationframe的最简单用法是一次又一次地调用它,直到没有必要为止

我在开发小型图书馆时学到了本课

https://github.com/allenhwkim/jsanimation

用法

import {slideInRight} from 'jsanimation';
slideInRight(el);

答案 2 :(得分:0)

不,堆栈不会爆炸,因为 requestAnimationFrame 的回调是异步执行的。在整个调用堆栈被清除之前,异步代码永远不会运行。有关事件循环的说明,请参阅 this video

考虑这个演示来说明:

const fakeRAF = cb => setTimeout(cb);

(function rerender() {
  fakeRAF(rerender);
  console.log(Date.now());
})();

你可以让它运行一整天。当然,requestAnimationFramefakeRAF 做的工作要多得多,因为它在计算何时触发 cb 方面非常聪明,但是这个简单的演示足以证明它不是递归的,这要归功于setTimeout 提供异步 API。

顺便说一下,doesn't matter 无论是在函数的顶部还是底部调用 requestAnimationFramefakeRAF。函数中的所有同步代码都必须在回调被触发之前运行,这样就不会出现下一帧踩到前一帧之类的问题。

答案 3 :(得分:-1)

在第一次render()调用之后,RequestAnimationFrame将异步处理你的渲染函数,每秒约60次调用它。您的函数不是递归的,因为Javascript将继续执行代码。

但是,您应该仅在渲染函数的最末端使用RequestAnimationFrame,作为函数的最后一个命令。想象一下,你有一个大场景,有很多动画:在完成参数更新之前请求下一帧,可能会造成巨大的混乱。

您还可以使用setTimeout处理动画,使用所需的帧速率调用render方法,如下所示:

var desideredFrameRate = 60;

window.myRequestAnimationFrame = function(callback) {

    setTimeout(callback, 1000/desiredFrameRate);

}