Os programadores de JavaScript estão acostumados a fingir paralelismo, mas há uma maneira de alcançar o verdadeiro paralelismo que você deve usar agora.

O JavaScript pode ter problemas com tarefas de alto desempenho porque é uma linguagem de thread único. Usando o paralelismo, você pode obter execução multithread em JavaScript e melhorar o desempenho e a capacidade de resposta de seus aplicativos da web modernos.

Paralelismo na programação JavaScript

O paralelismo é crucial na computação moderna para melhorar o desempenho e a escalabilidade. Ele faz isso utilizando efetivamente os recursos disponíveis.

Uma técnica comum usada para obter paralelismo na programação é o multithreading. O encadeamento JavaScript, no entanto, é um sistema de encadeamento único e pode manipular apenas uma tarefa por vez. Isso significa que ele não está familiarizado com execuções de programas paralelos.

JavaScript simula programação paralela

Um equívoco comum sobre paralelismo é que você pode alcançá-lo usando técnicas de programação assíncrona como async/await, retornos de chamada e promessas:

instagram viewer
// Função Async/await que simula uma requisição de rede
assíncronofunçãobuscar dados() {
const resposta = aguardam buscar();
const dados = aguardam resposta.json();
retornar dados;
}

// Função callback que registra os dados buscados no console
funçãologData(dados) {
console.log (dados);
}

// Método Promise.all() que executa várias promessas em paralelo
Promessa.todos([
buscarData(),
buscarData(),
]).então((resultados) => {
console.log (resultados);
});

// Chama a função fetchData e passa a função logData como callback
fetchData().then (logData);

Na verdade, essas técnicas não executam código em paralelo. O JavaScript usa o loop de eventos para imitar a programação paralela em seu design de thread único.

O loop de eventos é uma parte fundamental do ambiente de tempo de execução do JavaScript. Ele permite que você execute operações assíncronas, como solicitações de rede, em segundo plano sem bloquear o thread único principal.

O loop de eventos verifica constantemente novos eventos ou tarefas em uma fila e os executa um a um sequencialmente. Essa técnica permite que o JavaScript alcance simultaneidade e paralelismo teórico.

Simultaneidade vs. Paralelismo

Simultaneidade e paralelismo são muitas vezes mal compreendidos e trocados no mundo do JavaScript.

A simultaneidade em JavaScript refere-se à capacidade de executar várias tarefas sobrepondo a execução das tarefas. Onde uma tarefa pode começar antes que outra seja concluída, mas as tarefas não podem começar nem terminar simultaneamente. Isso permite que o JavaScript lide com operações com eficiência, como buscar dados de uma API REST ou ler arquivos, sem bloquear o thread de execução principal.

O paralelismo, por outro lado, refere-se à capacidade de executar várias tarefas simultaneamente em vários threads. Esses threads em segundo plano podem executar tarefas de forma independente e simultânea. Isso abre oportunidades para alcançar o verdadeiro paralelismo em aplicativos JavaScript.

Os aplicativos de JavaScript podem alcançar o verdadeiro paralelismo por meio de o uso de Web Workers.

Trabalhadores da Web introduzem o paralelismo no JavaScript

Os Web Workers são um recurso dos navegadores da Web modernos que permitem que o código JavaScript seja executado em threads de segundo plano, separados do thread de execução principal. Ao contrário do thread principal, que lida com as interações do usuário e as atualizações da interface do usuário. O Web Worker seria dedicado a executar tarefas computacionalmente intensivas.

Abaixo está uma representação em diagrama da operação de um Web Worker em JavaScript.

O thread principal e o Web Worker podem se comunicar usando a passagem de mensagens. Usando o postar mensagem método para enviar mensagens e o na mensagem manipulador de eventos para receber mensagens, você pode passar instruções ou dados para frente e para trás.

Criando um Web Worker

Para criar um Web Worker, você precisa criar um arquivo JavaScript separado.

Aqui está um exemplo:

// main.js

// Cria um novo Web Worker
const trabalhador = novo Trabalhador('trabalhador.js');

// Envia uma mensagem para o Web Worker
trabalhador.postMessage('Olá do tópico principal!');

// Escuta as mensagens do Web Worker
worker.onmessage = função(evento) {
console.registro('Mensagem recebida do Web Worker:', event.data);
};

O exemplo acima cria um novo Web Worker passando o caminho para o script do worker (trabalhador.js) como argumento para Trabalhador construtor. Você pode enviar uma mensagem para o Web Worker usando o postar mensagem e escute as mensagens do Web Worker usando o método na mensagem manipulador de eventos.

Você deve então criar o script de trabalho (trabalhador.js) arquivo:

// trabalhador.js

// Escuta as mensagens da thread principal
self.onmessage = função(evento) {
console.registro('Mensagem recebida do thread principal:', event.data);

// Envia uma mensagem de volta para a thread principal
self.postMessage("Olá de worker.js!");
};

O script Web Worker escuta as mensagens do thread principal usando o na mensagem manipulador de eventos. Ao receber uma mensagem, você desconecta a mensagem dentro evento.dados e enviar uma nova mensagem para o thread principal com o postar mensagem método.

Aproveitando o paralelismo com Web workers

O principal caso de uso para Web Workers é a execução de tarefas JavaScript com uso intensivo de computação em paralelo. Descarregando essas tarefas para Web Workers, você pode obter melhorias de desempenho significativas.

Aqui está um exemplo de uso de um web worker para realizar um cálculo pesado:

// main.js

const trabalhador = novo Trabalhador('trabalhador.js');

// Envia dados para o Web Worker para cálculo
trabalhador.postMessage([1, 2, 3, 4, 5]);

// Ouça o resultado do Web Worker
worker.onmessage = função(evento) {
const resultado = evento.dados;
console.registro('Resultado do cálculo:', resultado);
};

Worker.js:

// Escuta os dados da thread principal
self.onmessage = função (evento) {
const números = evento.dados;

const resultado = performHeavyCalculation (números);

// Envia o resultado de volta para a thread principal
self.postMessage (resultado);
};

funçãoperformHeavyCalculation(dados) {
// Executa um cálculo complexo no array de números
retornar dados
.mapa((número) =>Matemática.pow (número, 3)) // Cubo cada número
.filtro((número) => número % 20) // Filtra números pares
.reduzir((soma, número) => soma + número, 0); // Soma todos os números
}

Neste exemplo, você passa uma matriz de números do thread principal para o Web Worker. O Web Worker executa a computação usando a matriz de dados fornecida e envia o resultado de volta para o thread principal. O performHeavyCalculation() A função mapeia cada número para seu cubo, filtra os números pares e finalmente os soma.

Limitações e Considerações

Embora os Web Workers forneçam um mecanismo para obter paralelismo em JavaScript, é importante considerar algumas limitações e considerações:

  • Sem Memória Compartilhada: Web Workers operam em threads separados e não compartilham memória com o thread principal. Portanto, eles não podem acessar diretamente variáveis ​​ou objetos do thread principal sem passagem de mensagem.
  • Serialização e desserialização: ao passar dados entre o thread principal e os Web Workers, você precisa serializar e desserializar os dados, pois a transmissão de mensagens é uma comunicação baseada em texto. Esse processo gera um custo de desempenho e pode afetar o desempenho geral do aplicativo.
  • Suporte do navegador: embora os Web Workers sejam bem suportados na maioria dos navegadores modernos, alguns navegadores mais antigos ou ambientes limitados podem ter suporte parcial ou nenhum suporte para Web Workers.

Alcançar verdadeiro paralelismo em JavaScript

O paralelismo em JavaScript é um conceito empolgante que permite a verdadeira execução simultânea de tarefas, mesmo em uma linguagem principalmente de thread único. Com a introdução do Web Workers, você pode aproveitar o poder do paralelismo e obter melhorias significativas de desempenho em seus aplicativos JavaScript.