Рекурсия в JavaScript?
Это не нормальное решение прежде всего потому что функции знают о:
1. существовании друг друга
2. существовании некоего правила последовательности их вызова

Такой код называется высокосвязным. Высокосвязный код дорого поддерживать потому что приходится учитывать множество деталей его реализации. Учебники рекомендуют создавать как можно более обособленные функци: так называемые "чистые функции".

Сделать функции чище можно, например, так:

const delay = timeout =>
    Promise(resolve => setTimeout(() => resolve(), timeout));

async function delayedQueue() {
    first();
    await delay(1000);
    second();
    await delay(1000);
    third();
}

delayedQueue();

Как видите, теперь функции, которые необходимо вызвать с задержкой, не подозревают о существовании друг друга, а само правило последовательности их вызова инкапсулировано в отдельной функции delayedQueue.
одно слово: Promise