Таймер в цикле Node.js
Я новичок в Node.js и JavaScript в целом. Мне нужно чтобы выполнялся цикл n кол-во раз с промежутком в секунду, и после него уже выполнялись другие команды. Я пытался использовать setTimeout() внутри цикла for(), но это не дало никаких результатов, к примеру у меня цикл выполняется 10 раз, но в таком случае у меня все 10 таймеров запускаются почти одновременно. Потом отказался от for() и написал на setInterval() с i++ и if(i=4) {clearInterval()}. Дало определённые плоды, но последующие команды выполняются сразу после старта функции, а не по окончанию её.
Чтобы было более понятно приложу как должно было выглядеть в моей задумке.
0 секунда
1 секунда
И т.д.
Цикл окончен
А как выглядит на деле:
0 секунда
Цикл окончен
1 секунда
И т.д.
Ответы (2 шт):
Вам стоит разобраться, как в 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));
}
// Остальные команды...
})();
Если вам необходимо рекурсивно и последовательно выполнить итерацию, вы также можете применить рекурсию с асинхронным подходом, таким образом:
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);