2013-09-18 2 views
4

Я пытаюсь запустить функцию для каждого миллисекунды. Чтобы достичь этого, я просто предпочел использовать концепцию setInterval в javascript. Мой код приведен ниже,Запуск функции для каждого миллисекунда

HTML:

<div id=test>0.0</div> 

Сценарий:

var xVal = 0; 
var xElement = null; 

xElement = document.getElementById("test"); 
var Interval = window.setInterval(startWatch, 1); 


function startWatch(){ 

    xVal += 1; 
    xElement.innerHTML = xVal; 

} 

поэтому выше код работает отлично. Но пока я тестирую результат с реальными часами, реальным часам требуется 1000 миллисекунд, чтобы завершить 1 секунду, и в то же время для завершения потребуется более 1000 миллисекунд.

DEMO

Может кто-нибудь сказать мне,

Есть ли какие-либо ошибки с моим кодом? Если да, то скажите мне, как точно показывать миллисекунды?

+4

Браузер не является системой реального времени и любой сегмент JS может занять> 1 миллисекунду, чтобы закончить. Использование 1 миллисекундных интервалов не является хорошим решением. –

ответ

7

В вашем коде нет ошибок, но таймеры JavaScript (setInterval и setTimeout) are not precise. Браузеры не могут выполнить такой короткий интервал. Поэтому я боюсь, что нет никакого способа точно увеличивать миллисекунды на единицу и отображать обновления в веб-браузере. В любом случае, это даже не видно человеческому глазу!

Точная обходной будет включать больший интервал, и временные метки, чтобы вычислить истекшее время в миллисекундах:

var start = new Date().getTime(); 
setInterval(function() { 
    var now = new Date().getTime(); 
    xElement.innerHTML = (now - start) + 'ms elapsed'; 
}, 40); 
+0

Предположим, хочу ли я имитировать стоп-часы, что было бы невозможно с веб-приложениями? Правильно.? –

+1

Смотрите мое обновление. Возможно, что невозможно использовать 1 мс прирост и ожидать визуального обновления. В любом случае, это даже не видно человеческому глазу. – bfavaretto

0

setInterval обратного вызова, вероятно, не произойдет с точностью до миллисекунды, так как нить таймер работает возможно, даже не будет работать, когда наступит время, или браузер закроет события, или любой другой из нескольких вещей.

Кроме того, поскольку большинство движков Javascript однопоточные, то, что может сделать реализация setInterval, - это когда это запускает, запускает обратный вызов и затем перезагружает часы для следующего вызова. Поскольку вы выполняете некоторые манипуляции с DOM, это может занять несколько миллисекунд.

Короче говоря, вы ожидаете поведения операционной системы реального времени от интерпретатора, работающего внутри другого приложения, в дополнение к тому, что более чем вероятно не RTOS.

4

Вы не можете. Существует минимальная задержка, которую используют браузеры. Вы не можете запускать функцию каждые миллисекунды.

Из документации Mozilla,:

... 4ms определяется спецификацией HTML5 и соответствует во всех браузерах ...

Источник: https://developer.mozilla.org/en-US/docs/Web/API/window.setTimeout#Minimum.2F_maximum_delay_and_timeout_nesting

2

Вы можете» t сделать это, используя ваш метод из-за задержки, отображающей HTML и выполняющего интервал.Выполнение этого способа будет отображать время правильно при 60FPS.

http://jsfiddle.net/3hEs4/3/

var xElement = null; 
var startTime = new Date(); 

xElement = document.getElementById("test"); 
var Interval = window.setInterval(startWatch, 17); 


function startWatch(){ 
    var currentTime = new Date(); 
    xElement.innerHTML = currentTime - startTime; 
} 

Вы также можете посмотреть в использовании requestanimationframe вместо закодированного setInterval подобное.

+1

Есть ли причина для жесткого кодирования, что 17.? –

+0

Да, время между кадрами с 60FPS равно 1000/60 ~ = 16,67мс. Закругленное до 17. – PherricOxide

+0

вы можете использовать просто 1000/60 как аргумент вместо hardcoded 17 :) –

3

DOM не может фактически обновить 1000 раз в секунду. Ваш монитор не может даже отображать 1000 кадров за одну секунду, если на то пошло. Рассчитайте разницу между временем начала и текущее время в миллисекундах в вашей функции и использовать это:

(function(){ 
    var xElement = document.getElementById("test"); 
    var start = new Date; 

    (function update(){ 
     xElement.innerHTML = (new Date - start); 

     setTimeout(update, 0); 
    })(); 
}(); 

Updated fiddle

+0

+1 для использования рекурсивного 'setTimeout' в отличие от' setInterval'. – War10ck

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