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.