无限期重复异步功能,无需递归/承诺

时间:2018-12-27 16:31:13

标签: javascript node.js asynchronous callback promise

我想在完成执行后重复调用异步函数。
异步函数在完成时会调用其回调参数,因此我可以通过使用回调递归调用函数来实现此目的:

const fn = () => asyncFn(fn);

但是,由于NodeJS不再支持尾部调用优化,因此该方法最终会导致堆栈溢出。

更好的方法是使用ES6 Promise:

async function fn() {
  while (true) {
    await new Promise(asyncFn);
  }
}

还有其他方法吗?在引入Promise之前如何做?

1 个答案:

答案 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())