Повторять асинхронную функцию бесконечно без рекурсии / Обещание - PullRequest
0 голосов
/ 27 декабря 2018

Я хочу многократно вызывать асинхронную функцию после завершения выполнения.
Асинхронная функция вызывает свой аргумент обратного вызова после завершения, поэтому я могу сделать это путем рекурсивного вызова функции с обратным вызовом:

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

Однако, поскольку NodeJS прекратил поддерживать оптимизацию хвостового вызова, этот метод в конечном итоге вызовет переполнение стека.

Лучшим способом является использование ES6 Promise:

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

Есть ли другой способсделать это?Как это будет сделано до введения Promise?

1 Ответ

0 голосов
/ 27 декабря 2018

Я думаю, что ваше первоначальное предположение о рекурсивной функции неверно.Когда вы вызываете асинхронную функцию, обратный вызов ставится в очередь, а функция продолжается и возвращается.Как только асинхронная функция разрешается, функция вызывается снова, но это после того, как она уже вернулась, поэтому стек не свернулся.

Здесь вы можете увидеть начало и конец функции:

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