5

作为标题,为什么requestAnimationFrame递归不会吃掉 RAM。这篇帖子说 V8 引擎没有针对tail call. 那是因为浏览器在背后做了什么吗?还是V8支持优化tail call

这是 MDN 的示例

function step(timestamp) {
  var progress = timestamp - start;
  d.style.left = Math.min(progress/10, 200) + "px";
  if (progress < 2000) {
    requestAnimationFrame(step);
  }
}

requestAnimationFrame(step);
4

1 回答 1

12

requestAnimationFrame通知浏览器它希望在帧需要绘制时立即执行回调函数。函数的闭包必须存储到回调完成,但之后它可以被垃圾回收,前提是它没有在其他地方引用。

这里没有递归,因为我们正在通过一个断开执行的事件循环。该函数不是在调用自身,而是要求被调用。每次它完成执行时,可以回收该位 RAM。

值得记住的是,如果step简单地调用它自己,那将是一个无限递归。在这种情况下,堆栈会爆炸。如果我们想象一个无法炸毁(或尾调用递归)的无限堆栈,它将阻塞事件循环并阻止任何其他代码运行,因为一次只能运行一个函数。

于 2013-07-29T14:27:30.880 回答