Мне нужно создать событие ровно через каждые 1 с.
Невозможно сделать это с точной точностью.
Время, прошедшее до setTimeout
, составляет минимальное гарантированное время, в котором будет работать ваш код, а не точное время.
Время представляет собой количество миллисекунд, которое JS Engine будет нажимать на функцию Event Queue. Как только функция находится в очереди событий, она запускается после всех текущих задач, присутствующих в очереди, таких как события и другие таймеры, которые создадут задержку.
Кроме того, никакая задача не может быть выполнена из очереди событий, пока выполняется какой-либо обычный JS-код, который также может создавать небольшие задержки.
Например, эта функция test
:
setTimeout(function test() {
console.log('second');
}, 0);
for (i = 0; i < 1000000; i++); // the number 1000000 is an arbitrary big number
console.log('first');
будет работать после того, как петли ниже его завершения, который будет больше, чем 0
миллисекунды прочь.
Фактически, если этот цикл был бесконечным, обратный вызов setTimeout
никогда не будет срабатывать.
Примечание: Как упомянуто NNNNNN в комментариях, фактическое минимальное время, как per the HTML5 spec, в котором setTimeout
будет толкать функцию в очередь событий является 4ms, независимо от того, мы помещаем меньше. Раньше этот предел составлял 10 мс.
MDN
В самом деле, 4 мс определяется спецификацией HTML5 и соответствует во всех браузерах, выпущенных в 2010 году и далее. До (Firefox 5.0/Thunderbird 5.0/SeaMonkey 2.2) минимальное значение таймаута для вложенных тайм-аутов составляло 10 мс.
Другими словами, вы * не можете * планировать функцию, выполняемую с * точным * временем. (Кроме того, в отношении тайм-аута 0 мс, даже после продолжительного цикла после него он будет по-прежнему составлять минимум 4 мс, прежде чем он запустится, потому что браузеры вокруг меньших задержек до 4 мс - хотя ваша точка о том, что другой код должен заканчиваться первым, все еще стоит.) – nnnnnn