代码之家  ›  专栏  ›  技术社区  ›  Roy Wang

无限重复异步函数,无递归/承诺

  •  0
  • Roy Wang  · 技术社区  · 6 年前

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

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

    但是,由于nodejs已经停止支持尾调用优化,此方法最终将导致堆栈溢出。

    更好的方法是使用ES6承诺:

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

    还有别的办法吗?在引进承诺之前,如何做?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Mark    6 年前

    我认为关于递归函数的初始假设是错误的。当调用异步函数时,回调被排队,函数继续并返回。一旦Async函数解析了函数,就会再次调用它,但这是在它已经返回之后,这样堆栈就不会结束。

    您可以在这里看到函数的开始和结束:

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