O que exatamente é um tick de loop de evento do Node.js?

Eu tenho me aprofundado mais na parte interna da arquitetura node.js, e um termo que vejo chegando muito é “tick” como em “próximo tick do loop de events” ou a function nextTick () .

O que eu não vi é uma definição sólida do que é exatamente um “tick”. Com base em vários artigos ( como este ), pude montar um conceito em minha mente, mas não tenho certeza de como ele é preciso.

Posso obter uma descrição precisa e detalhada de um tick de loop de evento node.js?

Lembre-se de que, embora o JavaScript seja de encadeamento único, todas as E / S e chamadas do nó para APIs nativas são assíncronas (usando mecanismos específicos da plataforma) ou executadas em um encadeamento separado. (Isso tudo é tratado através de libuv.)

Então, quando há dados disponíveis em um soquete ou uma function de API nativa retornou, precisamos de uma maneira sincronizada para invocar a function JavaScript que está interessada no evento específico que acabou de acontecer.

Não é seguro chamar apenas a function JS do encadeamento em que o evento nativo ocorreu pelos mesmos motivos que você encontraria em um aplicativo multiencadeado normal – condições de corrida, access não atômico à memory e assim por diante.

Então, o que fazemos é colocar o evento em uma fila de maneira segura. Em psuedocode simplista, algo como:

lock (queue) { queue.push(event); } 

Então, de volta ao encadeamento principal do JavaScript (mas no lado C das coisas), fazemos algo como:

 while (true) { // this is the beginning of a tick lock (queue) { var tickEvents = copy(queue); // copy the current queue items into thread-local memory queue.empty(); // ..and empty out the shared queue } for (var i = 0; i < tickEvents.length; i++) { InvokeJSFunction(tickEvents[i]); } // this the end of the tick } 

O while (true) (que na verdade não existe no código-fonte do nó; isso é puramente ilustrativo) representa o loop de events . O inner invoca a function JS para cada evento que estava na fila.

Isso é um tick: a chamada síncrona de zero ou mais funções de retorno de chamada associadas a qualquer evento externo. Quando a fila é esvaziada e a última function é retornada, o tick termina. Voltamos ao começo (o próximo tick) e verificamos os events que foram adicionados à fila de outros segmentos enquanto nosso JavaScript estava em execução .

O que pode adicionar coisas à fila?

  • process.nextTick
  • setTimeout / setInterval
  • E / S (coisas de fs , net e assim por diante)
  • funções intensivas do processador do crypto, como streams de criptografia, pbkdf2 e o PRNG (que são, na verdade, um exemplo de ...)
  • quaisquer módulos nativos que usam a fila de trabalho libuv para fazer chamadas de biblioteca C / C ++ síncronas parecerem assíncronas

Uma resposta mais simples para quem é novo no JavaScript:

A primeira coisa a entender é que o JavaScript é um “ambiente de thread único”. Isso se refere ao comportamento do JavaScript de executar seus blocos de código, um de cada vez, a partir do “loop de events” em um único thread. Abaixo há uma implementação rudimentar do loop de events tirada do livro de Kyle Simpson, ydkJS, e depois, uma explicação:

 // `eventLoop` is an array that acts as a queue (first-in, first-out) var eventLoop = [ ]; var event; // keep going "forever" while (true) { // perform a "tick" if (eventLoop.length > 0) { // get the next event in the queue event = eventLoop.shift(); // now, execute the next event try { event(); } catch (err) { reportError(err); } } } 

O primeiro loop while simula o loop de events. Um tick é o desenfileiramento de um evento da “fila de loop de events” e a execução do evento mencionado.

Por favor, veja a resposta de ‘Josh3796’ para uma explicação mais detalhada sobre o que acontece no desenfileiramento e na execução de um evento.

Também recomendo ler o livro de Kyle Simpson para aqueles que estão interessados ​​em obter uma compreensão profunda do JavaScript. É completamente gratuito e de código aberto e pode ser encontrado neste link: https://github.com/getify/You-Nont-Know-JS

A seção específica a que fiz referência pode ser encontrada aqui: https://github.com/getify/You-Dont-Know-JS/blob/master/async%20%26%20performance/ch1.md#event-loop