Muitas pessoas parecem não conseguir entender como o NodeJS de thread único pode competir com back-ends multithread.
Para descobrir o porquê, temos que entender o que realmente significa que o Nodejs é single-threaded.
O próprio JavaScript foi originalmente criado para fazer coisas simples como validar formulários, dar respostas, etc. Somente em 2009 o criador do Node.js, Ryan Dahl, tornou possível escrever código do lado do servidor usando JavaScript.
As linguagens do lado do servidor que suportam multithreading possuem várias estruturas e construções para sincronização entre threads e outros recursos orientados a threads.
Apoiar essas coisas significaria que o JavaScript precisaria mudar toda a linguagem, o que vai contra as ideias dos criadores do JavaScript. Portanto, para oferecer suporte a multithreading em JavaScript puro, Dahl teve que criar uma solução alternativa. Vamos dar uma olhada!
Como funciona o Node.js?
O Node.js usa dois tipos de threads: o thread principal, que é tratado pelo loop de eventos, e vários threads secundários em um conjunto de threads de trabalho.
O mecanismo do Event Loop Node.js para lidar com operações de E/S sem bloqueio – mesmo que o JavaScript seja de thread único – descarrega operações para o kernel do sistema quando possível. Quando uma operação JavaScript bloqueia um thread, o loop de eventos também é bloqueado.
Um pool de trabalhadores é um modelo de execução que gera e processa threads separados, depois executa tarefas de forma síncrona e retorna os resultados ao loop de eventos. O loop de eventos usa o resultado para executar o retorno de chamada fornecido.
Basicamente, o pool de trabalhadores lida com operações de E/S assíncronas – principalmente interações com o disco do sistema e a rede. Alguns módulos usam pools de trabalhadores prontos para uso, como fs (pesado em E/S) ou crypto (pesado em CPU). O pool de trabalhadores é implementado em libuv, o que causa um atraso leve, mas quase insignificante, quando o Node precisa transferir dados internamente entre JavaScript e C++.
Depois de entender o significado do loop de eventos e do pool de trabalho, vejamos o seguinte código:
No código acima, não precisamos esperar pelo evento de forma síncrona. Delegamos a tarefa de ler o arquivo ao pool de trabalhadores e chamamos a função fornecida com o resultado. Como o pool de trabalhadores possui seu próprio thread, o loop de eventos pode continuar executando normalmente durante a leitura do arquivo.
Deixe-me apresentar a você: trabalhador_threads
Com o lançamento do Node.js 10.5.0, o trabalhador_threads apareceu. Ele suporta a criação de aplicativos multithread simples em JavaScript.
Worker_threads é um pacote de módulo nodejs. Um thread trabalhador é um trecho de código (geralmente retirado de um arquivo) gerado em um thread separado.
É importante observar que os termos thread trabalhador, trabalhador e thread são frequentemente usados de forma intercambiável. Todos eles se referem à mesma coisa.
Threads de trabalho em Node.js são úteis para executar tarefas pesadas de JavaScript. Com a ajuda de threads, os Workers podem facilmente executar código JavaScript em paralelo, tornando-o mais rápido e eficiente. Podemos concluir tarefas pesadas sem perturbar o thread principal.
Threads de trabalho não foram introduzidos em versões mais antigas do Node.js. Portanto, primeiro atualize seu Node.js para começar.
Agora crie dois arquivos para implementar threads da seguinte forma:
Nome do arquivo: trabalhador.js
const { trabalhadorData, parentPort } = require('worker_threads'); console.log(`Escreva sobre como ${workerData} quer relaxar com os grandes`); parentPort.postMessage({ nome do arquivo: trabalhadorData, status: 'Concluído' });
Nome do arquivo: index.js
const { Trabalhador } = require('worker_threads'); const runSerice = (workerData) => { retornar nova Promessa((resolver, rejeitar) => { const trabalhador = new Trabalhador ('./worker.js', { trabalhadorData }); trabalhador.on('mensagem', resolver); trabalhador.on('erro', rejeitar); trabalhador.on('saída', (código) => { se (código! == 0) rejeitar(new Error(`Worker Thread interrompido com código de saída ${code}`)); }); }); }; const execução = assíncrono () => { const resultado = aguarda runSerice('Tunde Ednut'); console.log(resultado); }; run().catch((err) => console.error(err))
;