Node.js версия 0.10 была выпущена сегодня и представлена setImmediate
. Документация по изменениям API предлагает использовать его при выполнении рекурсивных nextTick
вызовов.
Из того, что MDN говорит, кажется, очень похоже на process.nextTick
.
Когда я должен использовать nextTick
и когда я должен использовать setImmediate
?
javascript
node.js
setimmediate
Бенджамин Грюнбаум
источник
источник
nextTick
быстрее, чемsetImmediate
при больших вычислениях.setImmediate
делает более подробно.setImmediate
, но не раньшеnextTick
?Ответы:
Используйте,
setImmediate
если вы хотите поставить функцию в очередь за любыми обратными вызовами событий ввода / вывода, которые уже находятся в очереди событий. Используетсяprocess.nextTick
для эффективной постановки в очередь функции в начале очереди событий, чтобы она выполнялась сразу после завершения текущей функции.Таким образом, в случае, когда вы пытаетесь разорвать долгосрочную работу с привязкой к ЦП с помощью рекурсии, вы теперь захотите использовать,
setImmediate
а неprocess.nextTick
ставить в очередь следующую итерацию, так как в противном случае любые обратные вызовы событий ввода / вывода не получили бы шанс бегать между итерациями.источник
requestAnimationFrame
потому что это не всегда происходит (я определенно видел это, я думаю, что пример был вкладкой, а не текущей вкладкой), и его можно вызвать до того, как страница завершит рисование (то есть браузер все еще занят рисованием).Как иллюстрация
даст следующий вывод
Я надеюсь, что это может помочь понять разницу.
Обновлено:
источник
For example, if we run the following script which is not within an I/O cycle (i.e. the main module), the order in which the two timers are executed is non-deterministic, as it is bound by the performance of the process:
Итак, этот ответ на самом деле не отвечает точной разнице, а является лишь примером, который может варьироваться в разных контекстахЯ думаю, что могу проиллюстрировать это довольно красиво. Так как
nextTick
вызывается в конце текущей операции, рекурсивный вызов может привести к блокировке продолжения цикла обработки событий.setImmediate
решает эту проблему, запуская фазу проверки цикла событий, позволяя циклу событий нормально продолжаться.источник: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/
Обратите внимание, что фаза проверки начинается сразу после фазы опроса. Это связано с тем, что фаза опроса и обратные вызовы ввода / вывода являются наиболее вероятными местами для выполнения ваших вызовов
setImmediate
. Таким образом, в идеале большинство из этих вызовов на самом деле будут довольно немедленными, просто не такими немедленными, как те,nextTick
которые проверяются после каждой операции и технически существуют вне цикла обработки событий.Давайте рассмотрим небольшой пример различия между
setImmediate
иprocess.nextTick
:Допустим, мы только что запустили эту программу и проходили первую итерацию цикла событий. Он вызовет
step
функцию с нулевой итерацией. Затем он зарегистрирует два обработчика, один дляsetImmediate
и один дляprocess.nextTick
. Затем мы рекурсивно вызываем эту функцию изsetImmediate
обработчика, который будет запущен на следующем этапе проверки.nextTick
Обработчик будет работать в конце текущей операции прерывания цикла обработки событий, так что даже если он был зарегистрирован вторым будет реально работать первым.Порядок заканчивается следующим образом:
nextTick
запускается по окончании текущей операции, начинается цикл следующего события, выполняются обычные фазы цикла события,setImmediate
запускается и рекурсивно вызывает нашуstep
функцию, чтобы начать процесс заново. Текущая операция заканчивается,nextTick
пожары и т. Д.Вывод приведенного выше кода будет:
Теперь давайте переместим наш рекурсивный вызов
step
в нашnextTick
обработчик вместоsetImmediate
.Теперь, когда мы переместили рекурсивный вызов
step
вnextTick
обработчик, все будет вести себя в другом порядке. Наша первая итерация цикла событий выполняется и вызываетstep
регистрацию какsetImmedaite
обработчика, так иnextTick
обработчика. После завершения текущей операции нашnextTick
обработчик запускает, который рекурсивно вызываетstep
и регистрирует другойsetImmediate
обработчик, а также другойnextTick
обработчик. ПосколькуnextTick
обработчик срабатывает после текущей операции, регистрацияnextTick
обработчика вnextTick
обработчике приведет к тому, что второй обработчик будет запущен сразу после завершения текущей операции обработчика. ЭтиnextTick
обработчики будут продолжать стрелять, предотвращая текущий цикл событий из когда - либо продолжения. Мы пройдем через все нашиnextTick
обработчики, прежде чем мы видим одинsetImmediate
обработчик огня.Вывод приведенного выше кода в конечном итоге будет:
Обратите внимание, что если бы мы не прерывали рекурсивный вызов и не прерывали его после 10 итераций, то
nextTick
вызовы продолжали бы рекурсивно и никогда не позволяли бы циклу обработки событий переходить к следующему этапу. ЭтоnextTick
может стать блокировкой при рекурсивном использовании, тогда какsetImmediate
срабатывает в следующем цикле событий, а установка другогоsetImmediate
обработчика изнутри одного вообще не прерывает текущий цикл событий, позволяя ему продолжать выполнение фаз цикла событий как обычно.Надеюсь, это поможет!
PS - Я согласен с другими комментаторами в том, что имена двух функций можно легко поменять местами, поскольку
nextTick
звучит так, как будто они будут срабатывать в следующем цикле событий, а не в конце текущего, а конец текущего цикла более «немедленный» «чем начало следующего цикла. О, хорошо, это то, что мы получаем по мере развития API, и люди начинают зависеть от существующих интерфейсов.источник
В комментариях к ответу явно не говорится, что nextTick сместился с макросемантики на микросемантику.
до узла 0.9 (когда был введен setImmediate), nextTick работал в начале следующего стека вызовов.
начиная с узла 0.9, nextTick работает в конце существующего стека вызовов, тогда как setImmediate находится в начале следующего стека вызовов
проверьте https://github.com/YuzuJS/setImmediate для инструментов и деталей
источник
Проще говоря, process.NextTick () будет выполняться при следующем тике цикла событий. Однако setImmediate, в основном, имеет отдельную фазу, которая гарантирует, что обратный вызов, зарегистрированный в setImmediate (), будет вызываться только после фазы обратного вызова IO и опроса.
Пожалуйста, обратитесь к этой ссылке для хорошего объяснения: https://medium.com/the-node-js-collection/what-you-should-know-to-really-understand-the-node-js-event-loop-and -ITS-метрика-c4907b19da4c
источник
Несколько отличных ответов, подробно описывающих, как они оба работают.
Просто добавив тот, который отвечает на конкретный вопрос:
Всегда используйте
setImmediate
.Цикл событий, таймеры и
process.nextTick()
документация Node.js включают в себя следующее:Ранее в документе он предупреждает, что
process.nextTick
может привести к ...Как выясняется,
process.nextTick
может даже голодатьPromises
:С другой стороны,
setImmediate
« легче рассуждать » и позволяет избежать таких проблем:Поэтому, если нет особой необходимости в уникальном поведении
process.nextTick
, рекомендуемый подход - « использоватьsetImmediate()
во всех случаях ».источник
Я рекомендую вам ознакомиться с разделом документации, посвященным Loop, чтобы лучше понять. Какой-то фрагмент, взятый оттуда:
У нас есть два вызова, которые похожи на пользователей, но их имена сбивают с толку.
process.nextTick () запускается сразу на той же фазе
setImmediate () запускается на следующей итерации или «галочке» цикла
событий
По сути, имена должны поменяться местами. process.nextTick () срабатывает быстрее, чем setImmediate (), но это артефакт прошлого, который вряд ли изменится.
источник