Почему setTimeout срабатывает раньше, чем должен?

У меня есть немного кода node.js как такового:

var start = Date.now();

setTimeout(function() {
    console.log(Date.now() - start);
    for (var i = 0; i < 100000; i++) {
    }
}, 1000);

setTimeout(function() {
    console.log(Date.now() - start);
}, 2000);

Что-то странное происходит, когда я запускаю его на своей машине. Время, которое я получаю, находится между 970 и 980 и где-то между 1970 и 1980. Почему я получаю время, которое раньше, чем время ожидания?


person Swarage    schedule 02.09.2014    source источник
comment
В каком браузере? Safari возвращает такие числа, как 1002 и 2001, аналогичные Chrome и Firefox.   -  person RobG    schedule 02.09.2014
comment
Прежде всего, вы должны удалить этот цикл for — использование подобных конструкций в JS никогда не будет хорошей идеей. В JS нет эквивалента функции sleep, и попытки создать аналогичный эффект с помощью таких длительных циклов — полная ерунда, которая почти во всех случаях приведет к непредсказуемым или ненадежным результатам.   -  person CBroe    schedule 02.09.2014
comment
Я получаю 1002 и 2002 соответственно.   -  person Derek 朕會功夫    schedule 02.09.2014
comment
Это всего лишь пример кода, и на самом деле я запускаю его на своем Linux-компьютере, а не в каком-либо браузере. У меня есть этот цикл просто для имитации события, которое требует времени.   -  person Swarage    schedule 02.09.2014
comment
Объект Date не должен быть особенно точным, некоторые реализации имеют точность только 15 мс. Рассмотрите возможность использования performance.now (ссылка MDN< /a>), если поддерживается.   -  person RobG    schedule 02.09.2014
comment
Я запустил ваш код на node.js в Windows и получил два числа, которые я ожидал: 1015 и 2001, которые в значительной степени соответствуют срабатыванию двух таймеров. Прямо сейчас я бы сказал, что ваши цифры не воспроизводимы.   -  person jfriend00    schedule 02.09.2014


Ответы (2)


Из setTimeOut документации по node.js:

Важно отметить, что ваш обратный вызов, вероятно, не будет вызываться ровно через миллисекунды задержки — Node.js не дает никаких гарантий ни в отношении точного времени срабатывания обратного вызова, ни в порядке срабатывания элементов. Обратный вызов будет вызываться как как можно ближе к указанному времени.

Однако можно поиграть с нанотаймером:
https://www.npmjs.org/package/nanotimer

Некоторые связанные вопросы:

Тем не менее, я думаю, что +/- 30 мс раньше - это многовато (по сравнению с большинством браузеров, с которыми мне приходилось играть, они обычно не более чем на 10 мс позже (пока так как процессор не на максимуме, то есть)).

person GitaarLAB    schedule 02.09.2014

Я считаю, что вы испытываете эти проблемы из-за точности даты. Он может варьироваться в зависимости от платформы и браузера.

Вот более подробная информация о точности Date.

В некоторых платформах, но вам часто придется смешивать и сочетать (определять, что доступно, и соответственно регрессировать).

person Cristi Mihai    schedule 02.09.2014