В чем разница между этими двумя и когда я буду использовать одно вместо другого?
javascript
node.js
Шломи Шварц
источник
источник
Ответы:
setTimeout - это просто вызов функции после завершения задержки. Всякий раз, когда вызывается функция, она не выполняется немедленно, а ставится в очередь, так что она выполняется после того, как все выполняющиеся и находящиеся в данный момент обработчики событий завершают работу первыми. setTimeout (, 0) по сути означает выполнение после выполнения всех текущих функций в текущей очереди. Нет никаких гарантий относительно того, сколько времени это может занять.
setImmediate в этом отношении аналогичен, за исключением того, что он не использует очередь функций. Он проверяет очередь обработчиков событий ввода-вывода. Если все события ввода-вывода в текущем снимке обработаны, выполняется обратный вызов. Он ставит их в очередь сразу после последнего обработчика ввода-вывода, что-то вроде process.nextTick. Так быстрее.
Также (setTimeout, 0) будет медленным, потому что он проверит таймер хотя бы один раз перед выполнением. Иногда это может быть вдвое медленнее. Вот эталон.
var Suite = require('benchmark').Suite var fs = require('fs') var suite = new Suite suite.add('deffered.resolve()', function(deferred) { deferred.resolve() }, {defer: true}) suite.add('setImmediate()', function(deferred) { setImmediate(function() { deferred.resolve() }) }, {defer: true}) suite.add('setTimeout(,0)', function(deferred) { setTimeout(function() { deferred.resolve() },0) }, {defer: true}) suite .on('cycle', function(event) { console.log(String(event.target)); }) .on('complete', function() { console.log('Fastest is ' + this.filter('fastest').pluck('name')); }) .run({async: true})
Выход
deffered.resolve() x 993 ops/sec ±0.67% (22 runs sampled) setImmediate() x 914 ops/sec ±2.48% (57 runs sampled) setTimeout(,0) x 445 ops/sec ±2.79% (82 runs sampled)
Первый дает представление о максимально быстрых звонках. Вы можете сами проверить, вызывается ли setTimeout вдвое реже, чем other. Также помните, что setImmediate будет адаптироваться к вызовам вашей файловой системы. Так что под нагрузкой он будет работать меньше. Я не думаю, что setTimeout может стать лучше.
setTimeout - ненавязчивый способ вызова функций через некоторое время. Это как в браузере. Возможно, он не подходит для серверной части (подумайте, почему я использовал benchmark.js, а не setTimeout).
источник
Отличная статья о том, как работает цикл событий, и устраняет некоторые заблуждения. http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/
Цитирование статьи:
setImmediate
обратные вызовы вызываются после завершения или истечения времени ожидания обратных вызовов очереди ввода-вывода. Обратные вызовы setImmediate помещаются в очередь проверки, которые обрабатываются после очереди ввода-вывода.setTimeout(fn, 0)
обратные вызовы помещаются в очередь таймера и будут вызываться после обратных вызовов ввода-вывода, а также обратных вызовов очереди проверки. В качестве цикла обработки событий сначала обрабатывайте очередь таймера на каждой итерации, поэтому какая из них будет выполнена первой, зависит от того, на какой фазе находится цикл событий.источник
setImmediate () предназначен для планирования немедленного выполнения обратного вызова после обратных вызовов событий ввода-вывода и до setTimeout и setInterval.
setTimeout () предназначен для планирования выполнения одноразового обратного вызова после задержки в миллисекундах.
Об этом говорится в документах.
setTimeout(function() { console.log('setTimeout') }, 0) setImmediate(function() { console.log('setImmediate') })
Если вы запустите приведенный выше код, результат будет таким ... даже несмотря на то, что в текущем документе указано, что «запланировать« немедленное »выполнение обратного вызова после обратных вызовов событий ввода-вывода и перед setTimeout и setInterval». ..
Результат ..
Если вы поместите свой пример в другой таймер, он всегда будет печатать setImmediate, за которым следует setTimeout.
setTimeout(function() { setTimeout(function() { console.log('setTimeout') }, 0); setImmediate(function() { console.log('setImmediate') }); }, 10);
источник
всегда используйте
setImmediate
, если вы действительно не уверены, что вам нужноsetTimeout(,0)
(но даже не представляю, зачем).setImmediate
обратный вызов почти всегда будет выполняться раньшеsetTimeout(,0)
, за исключением случаев, когда он вызывается в первом тике и вsetImmediate
обратном вызове .источник
setTimeout
следуетsetImmediate
использовать только тогда, когда показано, что это необходимо.Совершенно не удовлетворен предоставленными ответами. Я опубликовал здесь то, что, по моему мнению, лучше: qaru.site/questions/435 / ...
Вопросы - это возможный дубликат вопроса Почему поведение setTimeout (0) и setImmediate () не определено при использовании в основном модуле?
источник
Я думаю, что ответ Navya S неверен , вот мой тестовый код:
let set = new Set(); function orderTest() { let seq = []; let add = () => set.add(seq.join()); setTimeout(function () { setTimeout(function () { seq.push('setTimeout'); if (seq.length === 2) add(); }, 0); setImmediate(function () { seq.push('setImmediate'); if (seq.length === 2) add(); }); }, 10); } // loop 100 times for (let i = 0; i < 100; i++) { orderTest(); } setTimeout(() => { // will print one or two items, it's random for (item of set) { console.log(item); } }, 100);
Объяснения здесь
источник
setTimeout (fn, 0) можно использовать для предотвращения зависания браузера при массовом обновлении. например, в websocket.onmessage у вас могут быть изменения html, и если сообщения продолжают приходить, браузер может зависнуть при использовании setImmidiate
источник
Чтобы понять их глубоко, пожалуйста, однажды пройдите фазы цикла событий.
SetImmediate: выполняется на этапе «проверки». Проверка фаза называется после фазы I / O.
SetTimeOut: выполняется в фазе "таймера". Таймер фаза является первой фазой , но вызывается после I / O фазы, а также Проверка фазы.
Чтобы получить результат детерминированным образом, это будет зависеть от того, на какой фазе находится цикл событий; соответственно, мы можем использовать функцию из двух.
источник
используйте setImmediate (), чтобы не блокировать цикл событий. Обратный вызов будет запущен в следующем цикле событий, как только будет выполнен текущий.
используйте setTimeout () для контролируемых задержек. Функция будет запущена после указанной задержки. Минимальная задержка составляет 1 миллисекунду.
источник