Вывод с максимально приближенным значением к текущему времени, с корректировкой на время выполнения функции-обработчика
function startTimer(cb) {
var timer = {running: true};
function interval() {
if (timer.running === false) return;
console.log('tick: ', (new Date()).toISOString());
cb();
setTimeout(interval, 1100 - (Date.now() + 100) % 1000);
}
setTimeout(interval, 1100 - (Date.now() + 100) % 1000);
return timer;
}
function stopTimer(timer) {
timer.running = false;
}
// test
function payload() {
var start = Date.now();
for (var i = 0; i < 10000000; i++); // нагрузка
var stop = Date.now();
console.log('payload:', stop - start)
}
var timer = startTimer(payload);
Обратите внимание на 1100 - (Date.now() + 100) % 1000
Здесь происходит сдвиг от нулевой позиции, чтобы между вызовами таймеров было более 100мс.
Эту цифру можно регулировать. Как известно между вызовами не может быть менее 4мс, поэтому (учитывая небольшой запас) не рекомендую ставить меньше 10мс. При данном значении максимальное время выполнения обработчика, для избежания пропуска таймера, будет 989мс, если обработчик будет выполнятся дольше, то очередной вызов будет пропущен.