为什么requestAniamtionFrame不会导致堆栈溢出错误?

Why requestAniamtionFrame doesn't cause stack overflow error?

我想了解递归调用 requestAnimationFrame() 时浏览器的底层会发生什么。

我的浏览器控制台中有这样的 运行 代码:

function foo(){
    requestAnimationFrame(foo);
    console.log("foo");
}
foo()

结果: "foo" 正在不停地打印出来。

我的问题:我不知道我是如何不超过允许的堆栈大小的。

我认为正在发生的事情:

function callAsynchronously(callback){
    setTimeout(callback, 1);
}

function foobar(){
    callAsynchronously(foobar); // replacement for requestAnimationFrame
    console.log("hi");
}

foobar() // result is the same as before, non-stop printing

以上代码是我的可视化方式 requestAnimationFrame:

  1. foobar() 入栈
  2. callAsynchronously(foobar) 入栈
  3. callAsynchronously(foobar) 从堆栈弹出
  4. console.log("hi") 被放入堆栈/浏览器 api 将 foobar 回调放入某个队列 setTimeout 完成后
  5. console.log("hi") 从堆栈中弹出
  6. 浏览器看到空堆栈并将队列中的回调放入堆栈
  7. 重复

我假设 requestAnimationFrame 做了类似不超过允许的堆栈大小的事情,但我不确定是否仅此而已。这是否意味着只要我将堆栈大小保持在可接受的范围内,我就可以使用异步回调轰炸浏览器 api 而不会出现任何错误 运行ge?

requestAnimationFrame根据设备屏幕的刷新率调用。例如,如果您在 60hz 屏幕上观看,foo 函数将被调用 60 次。

在所有同步执行完成之前,

requestAnimationFrame 不会 运行。它安排给定的回调。它的行为非常像 setTimeout。它不是真正的递归,它只是看起来那样。这就是事件循环的本质。