2016-08-26 2 views
2

Мне нужно сгенерировать событие ровно через каждые 1 с. Я тестирую функцию SetTimeout следующим образом:Временное приложение в javascript

window.onload = function() { 
     var oldTime = Date.now(); 

     setTimeout(function printTime() { 
      newTime = Date.now(); 
      console.log(newTime - oldTime); 
      oldTime = newTime; 
      setTimeout(printTime, 1000); 
     }, 1000); 
    } 

Он возвращает 1s с немного смещение:

testTimeout.js:6 1005 
testTimeout.js:6 1006 
2testTimeout.js:6 1001 
testTimeout.js:6 1006 
testTimeout.js:6 1005 
testTimeout.js:6 1006 
testTimeout.js:6 1005 

Где смещение взялось? Это из-за расчета oldTime и newTime?

ответ

3

Мне нужно создать событие ровно через каждые 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 мс.

+1

Другими словами, вы * не можете * планировать функцию, выполняемую с * точным * временем. (Кроме того, в отношении тайм-аута 0 мс, даже после продолжительного цикла после него он будет по-прежнему составлять минимум 4 мс, прежде чем он запустится, потому что браузеры вокруг меньших задержек до 4 мс - хотя ваша точка о том, что другой код должен заканчиваться первым, все еще стоит.) – nnnnnn

Смежные вопросы