Вы правы, что неконтролируемая рекурсия может привести к исчерпанию ресурсов из-за бесконечного роста стека. Например, следующая программа Javascript будет аварийно завершена после того, как check()
будет выполнено достаточное количество раз без первого return
ing:
function check() {
check();
}
check();
Следующий код не завершится таким образом:
function check() {
setTimeout(check, 1000);
}
check();
Этот код может выполняться бесконечно, не исчерпывая стек, потому что каждый раз, когда запускается check()
, разрешается запуск до завершения и return
до его запуска в будущем.
Это работает, потому что функция setTimeout()
напрямую не запускается check()
. Вместо этого он сообщает среде выполнения Javascript запланировать выполнение check()
на 1 секунду в будущем. Когда он и check()
завершены, стек Javascript становится пустым. Через 1 секунду выполнение check()
ставится в очередь и в конечном итоге выполняется , пока стек Javascript свободен.
Поскольку стек Javascript должен быть очищен до запуска check()
, переполнения стека исключаются.