Как выполнить код точно 1000 раз за 1 секунду в JavaScript

n = 0;
var timer = setInterval(function() {
    if (n == 0) {
        console.log(new Date());
    }
    // execute some other code here
    n++;
    if (n == 1000) {
        clearInterval(timer);
        console.log(new Date());
    }
}, 1);

Ответы

Ответ 1

Вот демонстрация подхода для одного таймера на итерацию. Для выполнения 1000 "итераций" одного и того же обратного вызова требуется примерно 1 секунда. Конструкция грубая, поскольку это всего лишь пример.

jsFiddle Demo

//Function to compose the array of timers
function timers(count, callback){
  var timers = [];
  for(var i = 0; i < count; i++){
    timers.push(timer(callback,i));
  }
  return timers;
};
//Function to compose individual timer
function timer(callback, delay){
  return function(){
    setTimeout(callback,delay);
  };
};

//Usage
console.log("Start:",new Date()); //timestamp

var display = document.querySelector("#display");

var settings = { n : 0 };

display.innerHTML = settings.n;

//Arrange timers and callback
var set = timers(1000,function(){
    this.n++;
		display.innerHTML = this.n;
    if(this.n === 1000) console.log("End:",new Date());
}.bind(settings));

//Execute timers
for(var i = 0; i < set.length; i++){ set[i](); }
<div id="display">
</div>

Ответ 2

Таймеры Javascript в браузерах являются неточными (C было бы лучше для этого использования).

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

В течение одной секунды будет сложно иметь 1000 равномерно рассчитанных вызовов функции. Одна миллисекунда является низкой величиной, простое выполнение самой активированной функции (плюс накладные расходы на обработку таймеров), скорее всего, займет время около 1 мс (или, может быть, больше)... что означает, что интерпретатор JS вызывает функцию после 1 мс, выполняет код, а затем устанавливает новый таймер 1 мс. Следовательно, между вызовами существует более 1 мс.

интерпретатор JS делает что-то вроде

At t   call function     <-- this takes
       execute function  <-- some 
at t+x set new 1ms timer <-- time
etc...

Однако, если вы можете позволить завершить процесс в таймфрейме ближе к 1 секунде (чем 3-4 секунды, который у вас есть сейчас), делая как можно больше вызовов на 1 мс, это возможно.

var n = 0;

var timer= setInterval(function(){
          if(n++ == 0) {
                console.log(new Date());
          }
     }, 1);

setTimeout(function() {
         clearInterval(timer);
         console.log("Got n="+n+" at "+(new Date()));
     }, 1000);

Это в основном та же программа, что и ваша

  • n увеличивается на 1 мс
  • однако конец процесса контролируется еще одним 1-секундным таймером

В Chrome я получаю 252 n приращений, а две даты - на 1 секунду.

Ответ 3

Попробуйте использовать те же script в ECMA Script 6

'use strict';

var n = 0;

var timer = setInterval(() => { 
    n++;
}, 1);
console.log( new Date() );

setTimeout(() => {
 clearInterval(timer);
 console.log("Final N Value: "+n+" at "+ (new Date()) );
}, 1000);