我有一个异步函数,想要连续调用多次。
问题是,“多次”可能是几十万或数百万次...
显而易见的方法是从回调函数中再次调用相同的函数:
function foo()
{
asyncBar(foo);
}
当然,需要一些逻辑来停止递归。问题是堆栈是否会填充调用并在某些时候导致堆栈溢出?
我有一个异步函数,想要连续调用多次。
问题是,“多次”可能是几十万或数百万次...
显而易见的方法是从回调函数中再次调用相同的函数:
function foo()
{
asyncBar(foo);
}
当然,需要一些逻辑来停止递归。问题是堆栈是否会填充调用并在某些时候导致堆栈溢出?
问题是堆栈是否正在充满调用,并可能导致在某一点上出现stackoverflow错误?
不会。 如果asyncBar()
异步调用传递的回调函数,则不会有堆栈积累。
在您的代码中:
function foo() {
asyncBar(foo);
}
这里是正在发生的事情,逐步解释:
foo()
。asyncBar(foo)
。asyncBar
是异步的,这意味着它启动了一个异步操作(假设它是一个 http GET 请求,但任何异步操作都可以)。异步操作被初始化,但是 asyncBar()
立即返回。foo()
的初始调用返回,并且堆栈完全展开。现在堆栈中没有 foo()
了。foo()
之后的任何代码都会继续运行,直到完成并返回到事件循环。foo
,所以它调用该函数并重新开始整个循环,回到步骤 2。没有堆栈积累。关键在于异步回调会在当前堆栈结束、展开并返回到系统后的某个时间点被调用。
问题是堆栈是否正在填充调用,并可能在某些点上导致堆栈溢出?
如果该方法是异步的,那么您将根本不会遇到stackoverflow。
请查看下面的示例
function f1(n)
{
if (n > 0 )
{
callAsynch(n, function(n){
f1(n-1)
});
}
}
callAsynch
可能是一个Ajax调用(或任何异步操作),它将回调方法作为参数传递。f1(n-1)
)附加到队列中,因此它不会在堆栈上积累。