Подтвердить что ты не робот

Выполняет ли Node.js минимальную задержку для setTimeout?

В браузерах, если вы используете setTimeout из функции, называемой setTimeout, будет введена минимальная задержка в 4 мс. Mozilla developer wiki описывает это поведение и упоминает, что он стал стандартизован в HTML5.

Node.js документация для setTimeout не упоминает о минимальной задержке. Однако документация функции process.nextTick описывает ее как более эффективную альтернативу setTimeout(fn, 0). Это говорит о возможности того, что он более эффективен, потому что он избегает этой задержки. В противном случае setTimeout(fn, 0) можно было бы оптимизировать, чтобы вести себя одинаково.

Обеспечивает ли Node.js минимальную задержку для setTimeout, как это делают веб-браузеры?

4b9b3361

Ответ 1

У него нет минимальной задержки, и на самом деле это проблема совместимости между браузерами и node. Таймеры полностью не определены в JavaScript (это спецификация DOM, которая не используется в Node, и даже не отслеживается браузерами) и Node реализует их просто из-за того, насколько они фундаментальны в истории JavaScript и как незаменимы они в противном случае.

Node использует libuv, который представляет собой кросс-платформенный уровень абстракции для системного уровня более низкого уровня, таких как файловая система, сетевые элементы и т.д. Одной из таких задач являются таймеры, которые Node предоставляют минимальную оболочку. На уровне libuv используемыми таймерами являются таймеры высокой точности для конкретной системы. В Windows, например, это реализовано с помощью QueryPerformanceFrequency и FileTimeToSystemTime, который обеспечивает разрешение, измеренное в наносекундах.

В Node, если вы укажете setTimeout(callback, 1), то он будет выполнен через миллисекунду позже (при условии, что система не задерживает его из-за переполнения). В браузерах минимальное время будет 4 миллисекунды, как указано спецификацией HTML5: https://developer.mozilla.org/en/DOM/window.setTimeout. Это не гарантированное время, как минимум. Ожидается, что большинство браузеров будут иметь разрешение ~ 15 мс, что влияет на анимацию DOM.

Одна действительная часть информации заключается в том, что тайм-ауты, установленные на одну и ту же миллисекунду, в течение того же кадра будут выполняться в том порядке, в котором они были поставлены в очередь. Если вам нужно:

  setTimeout(callback1, 1);
  setTimeout(callback2, 1);
  setTimeout(callback3, 1);
  setTimeout(callback4, 1);

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

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724280(v=vs.85).aspx

Ответ 2

Из этого теста не кажется, что он имеет минимальную задержку.

Если вы выполняете setTimeout() с длительностью 10ms и длинным возвращаемым значением в консоли, это то, что вы получаете:

 var timer = setTimeout(function(){ console.log(timer);}, 10);

 { _idleTimeout: 10,
  _onTimeout: [Function],
  _idlePrev: null,
  _idleNext: null,
  _idleStart: Sun, 28 Aug 2011 14:34:41 GMT } 

Аналогично, с продолжительностью 1ms вы получаете:

 var timer = setTimeout(function(){ console.log(timer);}, 1);

 { _idleTimeout: 1,
  _onTimeout: [Function],
  _idlePrev: null,
  _idleNext: null,
  _idleStart: Sun, 28 Aug 2011 14:34:59 GMT } 

Но если вы выполняете длительность 0, вы не получаете свойство _idleTimeout: вообще, что, по-видимому, предполагает, что обратный вызов вызывается немедленно, хотя и асинхронно.

var timer = setTimeout(function(){ console.log(timer);}, 0);

{ repeat: 0, callback: [Function] }

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

var start = Date.now();
var timer = setTimeout(function(){ console.log(timer, Date.now() - start );}, 0);

{ repeat: 0, callback: [Function] } 0

Эти тесты проводились с использованием Node.js 0.5.2.

Ответ 3

Следует отметить, что реализация таймера зависит от операционной системы. Например, я помню "старый добрый" вопрос JTimer, где разрешение таймера составляло 16 мс в Windows и ~ 1 мс на других платформах. Это почти наверняка стоит проверить на вашем конкретном сервере.