В разных браузерах setTimeout почему-то работает так же по разному. Если использовать данную функцию в ежесекундном таймере, то примерно через 10 минут расхождение в браузерах около 20 секунд, хотя запущены были они в одно время. Как-то это можно исправить?
И это нисколечки вас не должно тревожить (что бы понять почему это вообще происходит - почитайте про event loop). Если вам нужно точное время - Date.now(), с точностью до милисекунд.
Алексей Максимов: может, имелось в виду корректировка с помощью Date.now()? смотрите javascript.ru там про это подробно есть - и пути решения таких проблем
Алексей Максимов: и? у вас есть текущее время, у вас есть время события. По таймеру мы только обновляем значение, но мы не полагаемся на таймер. Мы просто вычисляем значение по изменению.
copal: предположим что мы выставляем таймер каждые 1000 милисекунд. То есть за 10 минут у нас будет 600 таймеров.
Предположим что в промежутке у нас таки что-то происходит, идет перерисовка DOM элементов, мы скролим страницу и т.д. То есть мы тратим процессорное время на всю эту ерунду. Это смещает наш таймер. Где-то больше где-то меньше, ну и не забываем о логике между срабатыванием таймера и установкой нового. То есть у нас есть целая куча различных вещей которые жрут CPU, есть очередь событий которые надо обработать (event loop), и наш теймер просто помещается куда-то в эту очередь.
В итоге это нормально что между срабатываниями кусочков кода из event loop происходит разброс в ~30 милисекунд в зависимости от производительности браузера (на мобильниках все будет совсем плохо).
copal: о какой синхронизации и с каким сервером вы говорите?
В JS все дико просто. setTimeout - это просто возможность положить вызов чего-либо в очередь. Это не штуки вроде прерываний и т.д. То есть если мы выставим setTimeout(fn, 0) и потом влепим бесконечный цикл, наш таймаут никогда не вызовется так как он следующий на выполнение в очереди, а нынешний кусок потока выполнения не собирается заканчивать выполняться.
copal: ну и опять же никто не мешает вводить поправки самому, не тупо лепить 1000 милисекунд постоянно добавляя доп время, а скажем смотреть когда нам надо вызвать функцию в следующий раз и тогда задержки будут еще меньше.
Алексей Максимов: Достаточно засекать время старта (new Date) и раз, например в минуту, пытаться синхронизировать, учитывая дельту между засечённым временем и текущим, на момент синхронизации.