Допустим, нужно разбирать очередь. Типовой подход: раз в пару секунд спрашивать SELECT * FROM queue
. Типовое решение: setInterval(checkQueue, 2000)
.
Беда!
Ты не знаешь, сколько времени у тебя займет checkQueue()
. Никто не обещал, что это будет быстро или что запрос и вовсе не зависнет в блокировке. setInterval()
ничего про это не знает, он снова вызовет метод — и привет, снежный ком. В лучшем случае у тебя упадет скрипт.
А на выходных — будь уверен: через минуту все блокировки снимутся и 30 запущенных checkQueue()
все вместе дружно начнут исполнять одни и те же задачи.
Правильное решение: регулярный вызов setTimeout()
в конце checkQueue()
.
Метод выполняется (за секунду или за минуту — неважно), и только потом снова себя вызывает через две секунды.
async function cycle() {
const jobs = await db.getQueue();
await runJobs(jobs);
setTimeout(cycle, 2000);
}
cycle();
Плюсы:
Бонус: можно ставить разные таймауты в зависимости от наличия задач в очереди.