Как избежать переполнение стека?
setTimeout не переполняет стек (статья, в которой затрагивается работа стэка, и setTimeout в том числе), но нужно не забывать об использовании clearTimeout, во избежание утечек памяти:let timeoutName = setTimeout(() => {
   // Делаем что-то...
   console.log('Hello, world!');
   // Мы сделали все что нужно: очищаем память.
   clearTimeout(timeoutName);
}, 5 * 1000);
setTimeout не переполняет стек, это как раз и есть один из способов бороться с этим. Можно также использовать setInterval. Вот статься на эту тему.