Это не рекурсивный вызов, потому что первый вызов eternal()
фактически закончился до того, как setTimeout()
называет следующий. Таким образом, это не техническая рекурсия и со временем не наращивает стек. Он может запускаться вечно без какого-либо наращивания, и это прекрасный способ сохранить что-то работающее снова и снова.
В ответ на один из ваших комментариев javascript не является многопоточным, поэтому он не создает несколько потоков для таймеров. Каждое событие таймера, которое срабатывает, просто помещает событие в очередь событий, и если в это время не запущено JS, это событие запускается (тем самым вызывая функцию обратного вызова). Если JS работает в то время, JS-движок ждет, пока выполняющийся в настоящее время JS не завершится, а затем будет обслуживать следующее событие в очереди событий (таким образом вызывая обратный вызов).
Ваш код должен работать нормально, так как он не исчерпывает память. У вас проблемы с этим? –
Нет, это потому, что на другом языке, таком как C# или Java, что-то вроде этого в конечном итоге приведет к исключению переполнения стека, потому что это будет рекурсивный вызов. –