Tanto quanto eu sei, os profissionais da Web precisam ser escritos em um arquivo JavaScript separado e chamados assim:
new Worker('longrunning.js')
Estou usando o compilador de fechamento para combinar e minificar todo o meu código-fonte JavaScript, e prefiro não ter meus trabalhadores em arquivos separados para distribuição. Existe alguma maneira de fazer isso?
new Worker(function() {
//Long-running work here
});
Dado que as funções de primeira classe são tão cruciais para o JavaScript, por que a maneira padrão de executar o trabalho em segundo plano precisa carregar um arquivo JavaScript inteiro do servidor da Web?
javascript
web-worker
Ben Dilts
fonte
fonte
var worker = new DynWorker(); worker.inject("foo", function(){...});
...Respostas:
http://www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers
Exemplo completo de trabalhador embutido BLOB:
fonte
A solução html5rocks de incorporar o código de trabalho da Web em HTML é bastante horrível.
E um blob de JavaScript escapado como uma string não é melhor, principalmente porque complica o fluxo de trabalho (o compilador Closure não pode operar em strings).
Pessoalmente, eu realmente gosto dos métodos toString, mas @ dan-man ISSO regex!
Minha abordagem preferida:
Suporte é a interseção dessas três tabelas:
No entanto, isso não funcionará para um SharedWorker , porque o URL deve ser uma correspondência exata, mesmo se o parâmetro opcional 'name' corresponder. Para um SharedWorker, você precisará de um arquivo JavaScript separado.
Atualização de 2015 - chega a singularidade do ServiceWorker
Agora, há uma maneira ainda mais poderosa de resolver esse problema. Novamente, armazene o código do trabalhador como uma função (em vez de uma sequência estática) e converta usando .toString () e insira o código no CacheStorage em uma URL estática de sua escolha.
Existem dois possíveis substitutos. ObjectURL como acima, ou mais perfeitamente, coloque um arquivo JavaScript real em /my_workers/worker1.js
As vantagens dessa abordagem são:
fonte
Você pode criar um único arquivo JavaScript que esteja ciente de seu contexto de execução e possa atuar como um script pai e um trabalhador. Vamos começar com uma estrutura básica para um arquivo como este:
Como você pode ver, o script contém todo o código do ponto de vista do pai e do trabalhador, verificando se sua própria instância individual é um trabalhador
!document
. Oscript_path
cálculo um tanto pesado é usado para calcular com precisão o caminho do script em relação à página pai, pois o caminho fornecidonew Worker
é relativo à página pai, não ao script.fonte
Usando o
Blob
método, que tal isso para uma fábrica de trabalhadores:Então você poderia usá-lo assim ...
EDITAR:
Acabei de estender essa idéia ainda mais para facilitar a comunicação entre threads: bridged-worker.js .
EDIT 2:
O link acima é para uma essência que eu criei. Mais tarde, alguém o transformou em um repo real .
fonte
Trabalhadores da Web operam em contextos totalmente separados como programas individuais.
Isso significa que o código não pode ser movido de um contexto para outro na forma de objeto, pois eles poderiam fazer referência a objetos por meio de fechamentos pertencentes ao outro contexto.
Isso é especialmente crucial, pois o ECMAScript foi projetado para ser uma linguagem de encadeamento único e, como os trabalhadores da Web operam em encadeamentos separados, você terá o risco de executar operações não seguras para encadeamento.
Isso novamente significa que os trabalhadores da Web precisam ser inicializados com o código no formato de origem.
A especificação do WHATWG diz
mas, infelizmente, isso não explica realmente por que não se pode ter permitido passar uma string com código-fonte para o construtor.
fonte
uma maneira melhor de ler para um trabalhador em linha ..
fonte
toString()
, extrair o corpo do corpo e colocá-lo em um Blob. Verifique na última resposta, eu tenho um exemplo #Pegar a resposta da Adria e colocá-la em uma função de copiar e colar que funciona com o Chrome e o FF atuais, mas não o IE10 (o trabalhador do blob causa um erro de segurança ).
E aqui está um exemplo de trabalho http://jsfiddle.net/ubershmekel/YYzvr/
fonte
Resposta recente (2018)
Você pode usar o Greenlet :
Exemplo:
fonte
Dependendo do seu caso de uso, você pode usar algo como
Um exemplo seria
fonte
Dê uma olhada no plugin vkThread. Com o htis plugin, você pode pegar qualquer função no código principal e executá-la em um thread (web worker). Portanto, você não precisa criar um "arquivo de trabalho da web" especial.
http://www.eslinstructor.net/vkthread/
--Vadim
fonte
Você pode usar trabalhadores da Web no mesmo campo javascript usando trabalhadores da Web embutidos.
O artigo abaixo abordará você para entender facilmente os trabalhadores da web e suas limitações e depuração de trabalhadores da web.
Domínio em webworkers
fonte
Eu acho que a melhor maneira de fazer isso é usando um objeto Blob, abaixo você pode ver um exemplo simples.
fonte
Tente usar o jThread. https://github.com/cheprasov/jThread
fonte
aqui console:
fonte
https://developer.mozilla.org/es/docs/Web/Guide/Performance/Using_web_workers
fonte
Use meu pequeno plugin https://github.com/zevero/worker-create
fonte
Então, acho que temos outra opção interessante para isso agora, graças aos literais de modelo no ES6. Isso nos permite dispensar a função extra worker (e seu escopo estranho) e escrever o código que se destina ao trabalhador como texto com várias linhas, como no caso em que estávamos usando para armazenar texto, mas sem precisar de um documento ou DOM. para fazer isso. Exemplo:
Aqui está um resumo do restante dessa abordagem .
Observe que podemos extrair quaisquer dependências de função extras que desejamos para o trabalhador, coletando-as em uma matriz e executando .toString em cada uma delas para reduzi-las também em strings (deve funcionar desde que sejam declarações de função) e anexando isso à string de script. Dessa forma, não precisamos importar scripts que talvez já incluíssemos no escopo do código que estamos escrevendo.
A única desvantagem real dessa versão em particular é que os linters não serão capazes de desvendar o código do operador de serviço (já que é apenas uma string), o que é uma vantagem para a "abordagem da função de operador separada".
fonte
Isso é apenas uma adição ao que foi mencionado acima - tenho ótimos modelos para testar os trabalhadores da web no jsFiddle. Em vez de Blob, ele usa a
?js
API jsFiddles :Modelos de trabalhador da Web normal e de trabalhador compartilhado estão disponíveis.
fonte
Descobri que o CodePen atualmente não possui
<script>
tags embutidas de destaque de sintaxe que não sãotype="text/javascript"
(ou que não têm nenhum atributo de tipo).Então, eu criei uma solução semelhante, mas um pouco diferente, usando blocos rotulados com
break
, que é a única maneira de recuperar uma<script>
marca sem criar uma função de invólucro (o que é desnecessário).fonte
Uma versão promissificada simples,,
Function#callAsWorker
que usa thisArg e argumentos (exatamente comocall
) e retorna uma promessa:fonte
close()
método para fechar o gancho de vida do trabalhador da web. developer.mozilla.org/pt-BR/docs/Web/API/WorkerGlobalScope/…close
função está obsoleta. No entanto, os trabalhadores podem ser demitidos . Eu adicionei isso agora.Eu uso código como este, você pode definir sua mensagem como uma função que não seja texto simples, para que o editor possa destacar seu código e o jshint funcionar.
fonte
Sim, é possível, eu fiz isso usando arquivos Blob e passando um retorno de chamada
Mostrarei a você o que uma classe que escrevi faz e como ela gerencia a execução de retornos de chamada em segundo plano.
Primeiro você instancia o
GenericWebWorker
com os dados que você gostaria de passar para o retorno de chamada que será executado noWeb Worker
, que inclui as funções que você deseja usar, neste caso, um número, uma data e uma função chamadablocker
Essa função bloqueadora executará um tempo infinito por n milissegundos
e então você usa assim
fonte
Você pode colocar o conteúdo do seu arquivo worker.js dentro de backticks (que permite uma constante de cadeia de linhas múltiplas) e criar o trabalhador a partir de um blob como este:
Isso é útil se, por qualquer motivo, você não quiser ter tags de script separadas para o trabalhador.
fonte
Outra solução é apenas agrupar o Worker em uma função e criar um blob chamando a função da seguinte maneira:
fonte
Uma linha para executar funções em trabalhadores:
Exemplo de uso:
fonte