Qual é a diferença entre os dois e quando vou usar um em vez do outro?
javascript
node.js
Shlomi Schwartz
fonte
fonte
Respostas:
setTimeout é simplesmente como chamar a função após o término do atraso. Sempre que uma função é chamada, ela não é executada imediatamente, mas enfileirada para que seja executada depois que todos os manipuladores de eventos em execução e atualmente enfileirados terminem primeiro. setTimeout (, 0) significa essencialmente executar depois que todas as funções atuais na fila atual forem executadas. Nenhuma garantia pode ser feita sobre quanto tempo isso pode levar.
setImmediate é semelhante nesse aspecto, exceto que não usa fila de funções. Ele verifica a fila de manipuladores de eventos de E / S. Se todos os eventos de E / S no instantâneo atual forem processados, ele executa o retorno de chamada. Ele os enfileira imediatamente após o último manipulador de E / S, de forma semelhante a process.nextTick. Portanto, é mais rápido.
Além disso, (setTimeout, 0) será lento porque verificará o cronômetro pelo menos uma vez antes de executar. Às vezes, pode ser duas vezes mais lento. Aqui está uma referência.
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})
Resultado
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)
Primeiro dá-se uma ideia das chamadas mais rápidas possíveis. Você pode verificar se setTimeout é chamado a metade das vezes que outro. Lembre-se também de que o setImmediate se ajustará às chamadas do seu sistema de arquivos. Portanto, sob carga, o desempenho será menor. Não acho que setTimeout possa fazer melhor.
setTimeout é uma forma não intrusiva de chamar funções depois de algum tempo. É exatamente como no navegador. Pode não ser adequado para o lado do servidor (pense por que usei benchmark.js e não setTimeout).
fonte
Um ótimo artigo sobre como funciona o loop de eventos e elimina alguns equívocos. http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/
Citando o artigo:
setImmediate
os retornos de chamada são chamados depois que os retornos de chamada da Fila de E / S são concluídos ou expiram. Os retornos de chamada setImmediate são colocados em Check Queue, que são processados após I / O Queue.setTimeout(fn, 0)
callbacks são colocados em Timer Queue e serão chamados após callbacks de I / O, bem como callbacks Check Queue. Como loop de evento, processe a fila do cronômetro primeiro em cada iteração, de forma que qual delas será executada primeiro depende de qual loop de evento de fase é.fonte
setImmediate () é para agendar a execução imediata de callback após callbacks de eventos de E / S e antes de setTimeout e setInterval.
setTimeout () é para agendar a execução de um retorno de chamada único após um atraso de milissegundos.
Isso é o que dizem os documentos.
setTimeout(function() { console.log('setTimeout') }, 0) setImmediate(function() { console.log('setImmediate') })
Se você executar o código acima, o resultado será assim ... embora o documento atual indique que "Para agendar a execução" imediata "do retorno de chamada após os retornos de chamada de eventos de E / S e antes de setTimeout e setInterval." ..
Resultado..
Se você envolver seu exemplo em outro cronômetro, ele sempre imprimirá setImmediate seguido por setTimeout.
setTimeout(function() { setTimeout(function() { console.log('setTimeout') }, 0); setImmediate(function() { console.log('setImmediate') }); }, 10);
fonte
use sempre
setImmediate
, a menos que você tenha certeza de que precisasetTimeout(,0)
(mas nem consigo imaginar para quê).setImmediate
o callback quase sempre será executado antessetTimeout(,0)
, exceto quando chamado no primeiro tick e nosetImmediate
callback.fonte
setTimeout
deve ser o ponto de partida, sendosetImmediate
usado somente quando for necessário.Totalmente insatisfeito com as respostas fornecidas. Publiquei o que considero uma resposta melhor aqui: https://stackoverflow.com/a/56724489/5992714
Perguntas é uma possível duplicata de Por que o comportamento de setTimeout (0) e setImmediate () é indefinido quando usado no módulo principal?
fonte
Acho que a resposta do Navya S não está correta, aqui está o meu código de teste:
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);
As explicações estão aqui
fonte
setTimeout (fn, 0) pode ser usado para evitar que o navegador congele em uma atualização massiva. por exemplo, em websocket.onmessage, você pode ter alterações de html e, se as mensagens continuarem chegando, o navegador pode congelar ao usar setImmidiate
fonte
Para entendê-los profundamente, passe uma vez pelas fases do loop de eventos.
SetImmediate: é executado na fase de "verificação". A fase de verificação é chamada após a fase de E / S.
SetTimeOut: É executado na fase de "cronômetro". A fase do temporizador é a primeira fase, mas é chamada após a fase de E / S , bem como a fase de verificação .
Para obter a saída de maneira determinística, dependerá de qual fase está o loop de eventos; consequentemente, podemos usar a função de dois.
fonte
use setImmediate () para não bloquear o loop de eventos. O retorno de chamada será executado no próximo loop de evento, assim que o atual for concluído.
use setTimeout () para atrasos controlados. A função será executada após o atraso especificado. O atraso mínimo é de 1 milissegundo.
fonte