Quando se trata de HTML5, as pessoas sempre falam sobre isso. Existem tantos recursos e APIs interessantes que são refrescantes. No entanto, muitos calçados infantis ainda permanecem no estágio semântico e ignoram o poder do HTML5.
Nesta seção discutiremos o Web-Worker multithread.
1. Deixe claro que o JavaScript é de thread únicoUma característica importante da linguagem JavaScript é que ela é de thread único, o que significa que só pode fazer uma coisa por vez.
Parece estranho, por que não projetá-lo com multithreading para melhorar a eficiência? Podemos assumir um cenário:
Suponha que JavaScript
tenha dois threads ao mesmo tempo. Um thread adiciona conteúdo a um determinado nó DOM
e o outro thread exclui o nó. Nesse caso, qual thread o navegador deve usar?
Como linguagem de script de navegador, o principal objetivo do JavaScript
é interagir com os usuários e manipular DOM
.
Isso determina que só pode ser single-threaded, caso contrário causará problemas de sincronização muito complexos. Para evitar complexidade, JavaScript
tem sido de thread único desde o seu nascimento. Isso se tornou um recurso central da linguagem e espera-se que seja difícil de mudar no curto prazo.
Threading único sempre foi um problema. Para aproveitar o poder de computação das CPU
multi-core, HTML5
propõe o padrão Web Worker
, que permite que scripts JavaScript
criem vários threads. No entanto, o thread filho é totalmente controlado pelo thread principal e não deve operar DOM
.
Portanto, este novo padrão não altera a natureza de thread único do JavaScript
.
Web Workers
é uma solução JavaScript
multithreading fornecida por navegadores modernos. Podemos encontrar muitos cenários de uso:
1. Podemos usar Web Worker
para realizar algumas operações computacionalmente intensivas;
2. A votação pode ser implementada e certos estados podem ser alterados;
3. Atualização do status da mensagem do cabeçalho, como notificação do número de mensagens no cabeçalho da página;
4. Interação do usuário de alta frequência, verificação ortográfica, por exemplo: ajudar os usuários a concluir a correção de erros de entrada e funções de correção com base nos hábitos de entrada do usuário, registros históricos, cache e outras informações
5. Criptografia: Às vezes, a criptografia pode consumir muito tempo, especialmente se você precisar criptografar muitos dados com frequência (por exemplo, criptografar dados antes de enviá-los ao servidor).
6. Pré-busca de dados: para otimizar seu site ou aplicativo web e melhorar o tempo de carregamento de dados, você pode usar Workers
para carregar alguns dados com antecedência caso você precise.
A criptografia é um ótimo cenário para usar Web Worker
porque não requer acesso DOM
ou outra mágica, apenas usa algoritmos para realizar cálculos. À medida que o público presta cada vez mais atenção aos dados pessoais sensíveis, a segurança e a encriptação da informação tornaram-se as principais prioridades. Isso pode ser refletido no recente incidente de vazamento de dados do usuário 12.306.
Uma vez realizado o cálculo no Worker, ele é transparente para o usuário e não afeta a experiência do usuário.
3. Compatibilidade 4. Conceitos básicos1. Primeiro lembre-se de julgar se é compatível
if (janela.Worker) {...}
2. Criar um novo worker
é fácil
const meuTrabalhador = new Trabalhador('trabalhador.js');
O método postMessage() e o manipulador de eventos onmessage são a magia negra dos Workers.
3. postMessage
é usado para enviar mensagens e onmessage
é usado para ouvir mensagens.
const trabalhador = new Trabalhador('src/worker.js');worker.onmessage = e => { console.log(e.data);};worker.postMessage('Como vai você!');
Quando usados no thread principal, onmessage
e postMessage()
devem ser pendurados no objeto worker
, mas isso não é obrigatório quando usados no worker
. A razão é que, dentro worker
, worker
é efetivamente o escopo global.
4. Tratamento de exceções:
trabalhador.onerror = function(erro) { console.log(error.message); lançar erro;};
5. Demitir worker
trabalhador.terminar();
O thread worker
é eliminado imediatamente, sem qualquer chance de concluir suas operações ou limpeza.
6. No thread worker
, workers
também podem chamar seu próprio método close
para fechar:
fechar();5. Início rápido
Para entender rapidamente, vamos dar um pequeno exemplo: a estrutura do projeto é a seguinte
├── index.html└── src ├── main.js └── trabalhador.js
HTML
<html><head> <title>Demonstração de trabalho na Web</title> <meta charset=UTF-8 /></head><body> <div id=app> Olá Jartto! /main.js></script></body></html>
principal.js
const trabalhador = new Worker('src/worker.js');worker.onmessage = e => { const mensagem = e.data; console.log(`[From Worker]: ${message}`); ('app').innerHTML = mensagem;};worker.postMessage('Bem escrito!');
Trabalho.js
onmessage = e => { const message = e.data; console.log(`[From Main]: ${message}`); pelo seu apoio ');
O código é muito simples. O tópico principal envia: "Está tão bem escrito!"
O web trabalhador recebeu a mensagem e descobriu que o conteúdo continha a palavra “bom” e a enviou de volta ao tópico principal: “Obrigado pelo seu apoio”.
6. Limitações 1. Dentro worker
, os nós DOM
não podem ser manipulados diretamente e os métodos e propriedades padrão do objeto window
não podem ser usados. No entanto, podemos usar um grande número de coisas no objeto window
, incluindo mecanismos de armazenamento de dados como WebSockets
, IndexedDB
e Data Store API
específica FireFox OS
.
Aqui está um exemplo, modificamos main.js
:
const trabalhador = new Worker('src/worker.js');worker.onmessage = e => { const mensagem = e.data; console.log(`[From Worker]: ${message}`); ('app').innerHTML = mensagem;};+ trabalhador.onerror = função(erro) {+ console.log(erro);+ trabalhador.terminate();+ };worker.postMessage('Bem escrito!');
Vamos modificar work.js
novamente
+ alert('jartto');onmessage = e => { const mensagem = e.data; console.log(`[From Main]: ${message}`); 1) { postMessage('Obrigado pelo seu apoio' }});
Neste momento, a execução reportará:
Isso ocorre porque: o contexto no qual worker.js
é executado é diferente do contexto no qual HTML
da página principal é executado. O objeto de nível superior não é Window
, o contexto global para a execução woker.js
, mas WorkerGlobalScope
. Deixe-nos explicar em detalhes.
2. A transferência de dados entre workers
e o thread principal é realizada por meio de um mecanismo de mensagem: ambas as partes usam o método postMessage()
para enviar suas próprias mensagens e usam o manipulador de eventos onmessage
para responder à mensagem (a mensagem está incluída em o atributo data
do evento Message
).
Neste processo, os dados não são compartilhados, mas copiados.
3. Restrição de mesma origem
O arquivo de script atribuído ao thread Worker
deve ter a mesma origem que o arquivo de script do thread principal.
4. Restrições de arquivo
O thread Worker
não pode ler arquivos locais, ou seja, não pode abrir o sistema de arquivos local (file://)
. O script que ele carrega deve vir do servidor.
5. Arquivos locais não permitidos
SecurityError não capturado: Falha ao criar um trabalhador:
script em '(caminho)/worker.js'
não pode ser acessado da origem 'null'.
O Chrome não permite carregar web workers ao executar scripts de um arquivo local.
Então, como resolver isso? Podemos iniciar um servidor local. Recomenda-se usar http-server
, que é simples e fácil de usar.
6. Política de Segurança de Conteúdo
worker
possui seu próprio contexto de execução, distinto do objeto document
que o criou. De modo geral, worker
não está restrito pela política de segurança de conteúdo document
(ou worker
pai) que o criou.
Vejamos um exemplo, supondo que um document
tenha a seguinte declaração de cabeçalho:
Política de segurança de conteúdo: script-src 'self'
Parte do propósito desta declaração é proibir o código de script contido nela de usar o método eval()
. No entanto, se o código do script criar um worker
, o código executado no contexto worker
poderá usar eval()
.
Para especificar um CSP para um trabalhador, a solicitação para enviar o código do trabalhador deve ser anexada a um CSP.
A única exceção é que se a origem do script worker
for um identificador globalmente exclusivo (por exemplo, sua URL
especifica um esquema de dados ou blob
), worker
herdará document
ou CSP
worker
que o criou.
Sobre, podemos encontrar a documentação no MDN
:
1. self
:
Podemos usar a propriedade self
de WorkerGlobalScope
para obter uma referência ao próprio objeto.
2. location
:
O atributo location
retorna WorkerLocation
associado ao thread quando ele foi criado. Ele representa a URL
absoluta do recurso de script usado para inicializar o thread de trabalho. Este local de recurso URL
não será alterado mesmo se a página for redirecionada várias vezes.
3. close
:
Feche o thread atual, semelhante a terminate
.
4. caches
:
O contexto atual possui CacheStorage
para garantir a disponibilidade offline e a resposta à solicitação pode ser customizada.
5. console
:
Sintaxe console
de suporte.
6. importScripts
Podemos carregar funções de biblioteca no worker
através url
através importScripts()
.
7. XMLHttpRequest
Com ele, solicitações Ajax
podem ser feitas.
8. Você pode usar:
Existem muitas API
que podem ser usadas, então não vou dar exemplos um por um aqui.
Quando worker
encontra um erro em execução, seu manipulador de eventos onerror
será chamado. Ele receberá um evento chamado error
que estende a interface ErrorEvent
. O evento não borbulha e pode ser cancelado.
Para evitar que a ação padrão seja acionada, o trabalhador pode chamar o método preventDefault() do evento de erro.
Geralmente usamos as três informações principais a seguir para eventos de erro:
trabalhador.onerror = function(erro) { console.log(error.message); lançar erro;};
O texto acima é todo o conteúdo deste artigo. Espero que seja útil para o estudo de todos. Também espero que todos apoiem a Rede VeVb Wulin.