Как работает setTimeout в Node.JS?

Я предполагаю, что как только он выполнил его в очереди, но в очереди есть какая-то уверенность, которую он будет вызывать именно после X миллисекунд? Или другие тяжелые задачи выше в очереди задерживают его?

Ответ 1

Семантика setTimeout примерно такая же, как в веб-браузере: аргумент timeout представляет собой minimum количество мс, ожидающих до выполнения, а не гарантию. Кроме того, передача 0, не номер или отрицательное число приведет к тому, что он будет ждать минимального количества мс. В Node это 1 мс, но в браузерах оно может достигать 50 мс.

Причина этого в том, что JavaScript не допускает JavaScript. Рассмотрим этот пример:

setTimeout(function () {
  console.log('boo')
}, 100)
var end = Date.now() + 5000
while (Date.now() < end) ;
console.log('imma let you finish but blocking the event loop is the best bug of all TIME')

Ниже приведен поток:

  • укажите время ожидания на 100 мс.
  • busywait для 5000ms.
  • вернуться в цикл событий. проверьте наличие отложенных таймеров и выполните.

Если это не так, тогда у вас может быть один бит JavaScript "прерывать" другой. Нам нужно было бы установить мьютексы и семафоры и т.д., Чтобы избежать такого сложного кода:

var a = 100;
setTimeout(function () {
  a = 0;
}, 0);
var b = a; // 100 or 0?

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

Это лучший демон для битвы, чем сложность премутации? Это зависит.

Ответ 2

Идея неблокирования заключается в том, что итерации цикла быстры. Поэтому для итерации для каждого тика должно хватить на достаточно короткое время, чтобы setTimeout был точным с разумной точностью (выкл., Возможно, менее 100 мс или около того).

В теории, хотя вы правы. Если я напишу приложение и заблокирую тик, то setTimeouts будет отложено. Поэтому, чтобы ответить на ваш вопрос, кто может обеспечить выполнение setTimeouts вовремя? Вы, написав неблокирующий код, можете контролировать степень точности почти до любой разумной степени точности.

Пока javascript является "однопоточным" с точки зрения выполнения кода (за исключением веб-работников и т.п.), это всегда произойдет. Однопоточный характер является огромным упрощением в большинстве случаев, но требует, чтобы неблокирующая идиома была успешной.

Попробуйте использовать этот код либо в своем браузере, либо в node, и вы увидите, что нет гарантии точности, напротив, setTimeout будет очень поздно:

var start = Date.now();

// expecting something close to 500
setTimeout(function(){ console.log(Date.now() - start); }, 500);

// fiddle with the number of iterations depending on how quick your machine is
for(var i=0; i<5000000; ++i){}

Если интерпретатор не оптимизирует петлю (что не на хроме), вы получите что-то в тысячах. Удалите петлю, и вы увидите ее 500 на носу...

Ответ 3

Единственный способ обеспечить выполнение кода - это разместить логику setTimeout в другом процессе.

Используйте дочерний модуль процесса, чтобы создать новую программу node.js, которая выполняет вашу логику и передает данные в этот процесс через какой-то поток (возможно, tcp).

Таким образом, даже если в вашем основном процессе запущен какой-то длинный блокирующий код, ваш дочерний процесс уже запустился сам и поместил setTimeout в новый процесс и новый поток и, таким образом, запустится, когда вы его ожидаете.

Дальнейшее усложнение происходит на аппаратном уровне, где у вас больше потоков, а затем процессов, и, следовательно, переключение контекста вызовет (очень незначительные) задержки с вашего ожидаемого времени. Это должно быть небрежным, и если это важно, вам нужно серьезно подумать о том, что вы пытаетесь сделать, почему вам нужна такая точность и какое альтернативное оборудование в реальном времени доступно для выполнения задания.

В общем случае использование дочерних процессов и запуск нескольких приложений node в виде отдельных процессов вместе с балансировщиком нагрузки или общим хранилищем данных (например, redis) важно для масштабирования вашего кода.

Ответ 4

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

setTimeout(function,time_in_mills);

здесь первый аргумент должен быть типом функции; Например, если вы хотите напечатать свое имя через 3 секунды, ваш код должен выглядеть примерно так, как показано ниже.

setTimeout(function(){console.log('your name')},3000);

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

setTimeout(function(){yourOtherMethod(parameter);},3000);

Ответ 5

setTimeout(callback,t) используется для выполнения обратного вызова после не менее t миллисекунд. Фактическая задержка зависит от многих внешних факторов, таких как зернистость таймера ОС и загрузка системы.

Итак, есть вероятность, что он будет вызван чуть позже установленного времени, но никогда не будет вызван раньше.

Таймер не может превышать 24,8 дня.