Таймер в цикле Node.js

Я новичок в Node.js и JavaScript в целом. Мне нужно чтобы выполнялся цикл n кол-во раз с промежутком в секунду, и после него уже выполнялись другие команды. Я пытался использовать setTimeout() внутри цикла for(), но это не дало никаких результатов, к примеру у меня цикл выполняется 10 раз, но в таком случае у меня все 10 таймеров запускаются почти одновременно. Потом отказался от for() и написал на setInterval() с i++ и if(i=4) {clearInterval()}. Дало определённые плоды, но последующие команды выполняются сразу после старта функции, а не по окончанию её.

Чтобы было более понятно приложу как должно было выглядеть в моей задумке.

0 секунда
1 секунда
И т.д.
Цикл окончен

А как выглядит на деле:

0 секунда 
Цикл окончен
1 секунда
И т.д.

Ответы (2 шт):

Автор решения: vsemozhebuty

Вам стоит разобраться, как в JS работает асинхронность: https://learn.javascript.ru/async

Если вы используете последнюю версию Node.js, там есть промисифицированные версии таймеров, с ними легче всё организовать:

const { setTimeout } = require('timers/promises');

(async function main() {
  for (let i = 0; i < 10; i++) {
    console.log(i);
    await setTimeout(1000);
  }
})();

Или, если использовать ESM с поддержкой await на верхнем уровне:

import { setTimeout }  from 'timers/promises';

for (let i = 0; i < 10; i++) {
  console.log(i);
  await setTimeout(1000);
}

С более старыми версиями Node.js:

(async function main() {
  for (let i = 0; i < 10; i++) {
    console.log(i);
    await new Promise((resolve) => setTimeout(resolve, 1000));
  }

  // Остальные команды...
})();
→ Ссылка
Автор решения: Alexander Yukal

Если вам необходимо рекурсивно и последовательно выполнить итерацию, вы также можете применить рекурсию с асинхронным подходом, таким образом:

function processRecursively(n, delay=1000, callback) {
    if (n > 0) {
        // что-то выполняем
        console.log(n);

        // рекурсивно вызываем самих себя (с нужными аргументами)
        setTimeout(processRecursively, delay, --n, delay, callback);
    } else {
        callback('done!');
    }
}

processRecursively(5, 1000, console.log);

→ Ссылка