为什么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
:
foobar()
入栈
callAsynchronously(foobar)
入栈
callAsynchronously(foobar)
从堆栈弹出
console.log("hi")
被放入堆栈/浏览器 api 将 foobar
回调放入某个队列 setTimeout
完成后
console.log("hi")
从堆栈中弹出
- 浏览器看到空堆栈并将队列中的回调放入堆栈
- 重复
我假设 requestAnimationFrame
做了类似不超过允许的堆栈大小的事情,但我不确定是否仅此而已。这是否意味着只要我将堆栈大小保持在可接受的范围内,我就可以使用异步回调轰炸浏览器 api 而不会出现任何错误 运行ge?
requestAnimationFrame
根据设备屏幕的刷新率调用。例如,如果您在 60hz 屏幕上观看,foo
函数将被调用 60 次。
在所有同步执行完成之前,requestAnimationFrame
不会 运行。它安排给定的回调。它的行为非常像 setTimeout
。它不是真正的递归,它只是看起来那样。这就是事件循环的本质。
我想了解递归调用 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
:
foobar()
入栈callAsynchronously(foobar)
入栈callAsynchronously(foobar)
从堆栈弹出console.log("hi")
被放入堆栈/浏览器 api 将foobar
回调放入某个队列setTimeout
完成后console.log("hi")
从堆栈中弹出- 浏览器看到空堆栈并将队列中的回调放入堆栈
- 重复
我假设 requestAnimationFrame
做了类似不超过允许的堆栈大小的事情,但我不确定是否仅此而已。这是否意味着只要我将堆栈大小保持在可接受的范围内,我就可以使用异步回调轰炸浏览器 api 而不会出现任何错误 运行ge?
requestAnimationFrame
根据设备屏幕的刷新率调用。例如,如果您在 60hz 屏幕上观看,foo
函数将被调用 60 次。
requestAnimationFrame
不会 运行。它安排给定的回调。它的行为非常像 setTimeout
。它不是真正的递归,它只是看起来那样。这就是事件循环的本质。