Como funciona o setTimeout no nó.JS?
acho que uma vez executado está na fila, mas na fila existe alguma garantia de que irá invocar exactamente depois de x milissegundos? Ou outras tarefas pesadas mais elevadas na fila Irão atrasá-la?
5 answers
A semântica do setTimeout é aproximadamente a mesma de um navegador web: o tempo-limite arg é um Número mínimo de ms para esperar antes de executar, Não uma garantia. Além disso, passar 0, um não-número, ou um número negativo, fará com que ele espere um número mínimo de ms. In Node, este é 1ms, mas em navegadores pode ser tanto quanto 50ms.
A razão para isso é que não há nenhuma preempção de JavaScript por JavaScript. Considere este exemplo:
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')
O fluxo aqui riz:
- marca o tempo limite para 100ms.
- busywait para 5000ms.
- volta ao ciclo do evento. verifique se há cronómetros pendentes e execute.
Se este não fosse o caso, então você poderia ter um pouco de JavaScript "interromper" outro. Teríamos de criar mutexes e semáforos e assim, para evitar que um código como este fosse extremamente difícil de raciocinar sobre:
var a = 100;
setTimeout(function () {
a = 0;
}, 0);
var b = a; // 100 or 0?
A unica-threadedness da execução JavaScript do Node torna muito mais simples trabalhar com mais do que a maioria dos outros estilos de concorrência. Claro que a troca é possível que uma parte mal comportada do programa bloqueie tudo com um ciclo infinito.
É um demónio melhor para combater do que a complexidade da prevenção? Depende.A ideia de não-bloqueio é que as iterações de laço são rápidas. Assim, para iterar para cada carrapato deve demorar um tempo suficiente para que o setTimeout seja preciso dentro de uma precisão razoável (desligado por talvez Teoricamente, embora tenhas razão. Se eu escrever um aplicativo e bloquear o tick, então setTimeouts serão adiados. Então, para responder à sua pergunta, Quem pode garantir que os setTimeouts executam a tempo? Você, escrevendo código não-bloqueante, pode controlar o grau de precisão até quase qualquer grau razoável de precisão.
Enquanto javascript for "single-threaded" em termos de execução de código (excluindo web-workers e afins), isso sempre acontecerá. A natureza simples é uma simplificação enorme na maioria dos casos, mas requer que o idioma não-bloqueante seja bem sucedido.
Tente este código no seu navegador ou no nó, e verá que não há nenhuma garantia de precisão, pelo contrário, o setTimeout será muito tardio:
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){}
A menos que o interpretador otimize o loop (o que não acontece no chrome), você terá algo nos milhares. Retire o laço e verá que são 500 no nariz...
A única maneira de garantir que o código é executado é colocar a sua lógica setTimeout num processo diferente.
Use o módulo de processo-filho para criar um novo nó.js programa que faz a sua lógica e passar dados para esse processo através de algum tipo de fluxo (talvez tcp).
Desta forma, mesmo que algum código de bloqueio longo esteja a correr no seu processo principal, o seu processo-filho já começou a si próprio e colocou um 'setTimeout' num novo processo e um novo tópico e irá, portanto, correr quando espera para.
A complicação adicional está a um nível de hardware onde você tem mais tópicos em execução, em seguida, processos e, portanto, a mudança de contexto irá causar (muito pouco) atrasos do seu tempo esperado. Isso deve ser negável e se isso importa você precisa considerar seriamente o que você está tentando fazer, por que você precisa de tal precisão e que tipo de hardware alternativo em tempo real está disponível para fazer o trabalho em vez disso.
Em geral, usando processos-filhos e executando aplicações de múltiplos nós como processos separados, juntamente com um balancer de carga ou armazenamento de dados compartilhados (como o redis) é importante para dimensionar seu código.
O SetTimeout é uma espécie de Thread , que detém uma operação durante um determinado tempo e executa.
setTimeout(function,time_in_mills);
Aqui o primeiro argumento deve ser um tipo de função, como exemplo se quiser imprimir o seu nome ao fim de 3 segundos, o seu código deve ser algo semelhante ao que está em baixo.
setTimeout(function(){console.log('your name')},3000);
A chave poitn para recordar é: o que quer que você queira fazer usando setTimeout método, faça-o dentro de uma função.se você quiser chamar algum outro método por parcing alguns parâmetros, o seu código deve ser como em baixo,
setTimeout(function(){yourOtherMethod(parameter);},3000);
Happy nodejs coding:)
setTimeout(callback,t)
é utilizado para executar callback Após, pelo menos, t milisegundo. O atraso real depende de muitos fatores externos, como granularidade do temporizador OS e carga do sistema.
Um temporizador não pode durar mais de 24,8 dias.