Я думаю, что ваше первоначальное предположение о рекурсивной функции неверно.Когда вы вызываете асинхронную функцию, обратный вызов ставится в очередь, а функция продолжается и возвращается.Как только асинхронная функция разрешается, функция вызывается снова, но это после того, как она уже вернулась, поэтому стек не свернулся.
Здесь вы можете увидеть начало и конец функции:
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())