我想在完成执行后重复调用异步函数。
异步函数在完成时会调用其回调参数,因此我可以通过使用回调递归调用函数来实现此目的:
const fn = () => asyncFn(fn);
但是,由于NodeJS不再支持尾部调用优化,因此该方法最终会导致堆栈溢出。
更好的方法是使用ES6 Promise:
async function fn() {
while (true) {
await new Promise(asyncFn);
}
}
还有其他方法吗?在引入Promise之前如何做?
答案 0 :(得分:3)
我认为您对递归函数的最初假设是错误的。当您调用异步函数时,回调将排队,函数将继续并返回。异步函数解析后,将再次调用该函数,但这是在它已经返回之后,因此堆栈不会结束。
您可以在这里看到函数的开始和结束:
const runAsync = () => {
console.log("starting async function")
setTimeout(() => {
let v = runAsync()
console.log("return val", v)
}, 1000)
return "async function return"
}
console.log("return: ", runAsync())
如果堆栈与此终止,您将永远看不到返回值。您将只看到每个呼叫的日志starting async function
。这是堆栈确实溢出的情况:
const recursiveFn = () => {
console.log("starting function")
let v = recursiveFn()
console.log("return val", v)
return "test" // never gets here
}
console.log("return: ", recursiveFn())