Por lo que puedo decir, los trabajadores web deben escribirse en un archivo JavaScript separado y llamarse así:
new Worker('longrunning.js')
Estoy usando el compilador de cierre para combinar y minimizar todo mi código fuente JavaScript, y prefiero no tener que tener a mis trabajadores en archivos separados para su distribución. Hay alguna manera de hacer esto?
new Worker(function() {
//Long-running work here
});
Dado que las funciones de primera clase son tan cruciales para JavaScript, ¿por qué la forma estándar de trabajo en segundo plano tiene que cargar otro archivo JavaScript completo desde el servidor web?
javascript
web-worker
Ben Dilts
fuente
fuente
var worker = new DynWorker(); worker.inject("foo", function(){...});
...Respuestas:
http://www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers
Ejemplo completo de trabajador en línea BLOB:
fuente
La solución html5rocks de incrustar el código del trabajador web en HTML es bastante horrible.
Y una gota de JavaScript escapado como cadena no es mejor, sobre todo porque complica el flujo de trabajo (el compilador de cierre no puede funcionar en cadenas).
Personalmente, me gustan mucho los métodos toString, pero @ dan-man ¡ ESA expresión regular!
Mi enfoque preferido:
El soporte es la intersección de estas tres tablas:
Sin embargo, esto no funcionará para un SharedWorker , porque la URL debe ser una coincidencia exacta, incluso si coincide el parámetro opcional 'nombre'. Para un SharedWorker, necesitará un archivo JavaScript separado.
Actualización 2015: llega la singularidad ServiceWorker
Ahora hay una forma aún más poderosa de resolver este problema. Nuevamente, almacene el código de trabajo como una función (en lugar de una cadena estática) y convierta usando .toString (), luego inserte el código en CacheStorage bajo una URL estática de su elección.
Hay dos posibles retrocesos. ObjectURL como arriba, o más fácilmente, coloque un archivo JavaScript real en /my_workers/worker1.js
Las ventajas de este enfoque son:
fuente
Puede crear un único archivo JavaScript que conozca su contexto de ejecución y pueda actuar como un script principal y como un trabajador. Comencemos con una estructura básica para un archivo como este:
Como puede ver, el script contiene todo el código tanto para el punto de vista del padre como del trabajador, verificando si su propia instancia individual es un trabajador con
!document
. Elscript_path
cálculo algo difícil de manejar se utiliza para calcular con precisión la ruta del script en relación con la página principal, ya que la ruta suministradanew Worker
es relativa a la página principal, no al script.fuente
Usando el
Blob
método, ¿qué tal esto para una fábrica de trabajadores:Entonces podrías usarlo así ...
EDITAR:
Acabo de ampliar esta idea para facilitar la comunicación entre hilos: bridged-worker.js .
EDITAR 2:
El enlace de arriba es a una esencia que creé. Luego, alguien más lo convirtió en un repositorio real .
fuente
Los trabajadores web operan en contextos completamente separados como programas individuales.
Esto significa que el código no se puede mover de un contexto a otro en forma de objeto, ya que podrían hacer referencia a objetos a través de cierres que pertenecen al otro contexto.
Esto es especialmente crucial ya que ECMAScript está diseñado para ser un lenguaje de subproceso único, y dado que los trabajadores web operan en subprocesos separados, entonces correría el riesgo de que se realicen operaciones no seguras para subprocesos.
Esto nuevamente significa que los trabajadores web deben inicializarse con el código en forma de fuente.
La especificación de WHATWG dice
pero desafortunadamente no explica realmente por qué uno no podría haber permitido pasar una cadena con código fuente al constructor.
fuente
Una mejor manera de leer para un trabajador en línea.
fuente
toString()
, extraer el cuerpo y luego ponerlo en un Blob. Verifique en la última respuesta, tengo un ejemploTomando la respuesta de Adria y poniéndola en una función copiable que funciona con Chrome y FF actuales pero no con IE10 (el trabajador de blob causa un error de seguridad ).
Y aquí hay un ejemplo de trabajo http://jsfiddle.net/ubershmekel/YYzvr/
fuente
Respuesta reciente (2018)
Puedes usar Greenlet :
Ejemplo:
fuente
Dependiendo de su caso de uso, puede usar algo como
Un ejemplo sería
fuente
Echa un vistazo al complemento vkThread. Con el complemento htis puede tomar cualquier función en su código principal y ejecutarla en un hilo (trabajador web). Por lo tanto, no necesita crear un "archivo de trabajador web" especial.
http://www.eslinstructor.net/vkthread/
--Vadim
fuente
Puede usar trabajadores web en el mismo archivo javascript usando trabajadores web en línea.
El siguiente artículo se dirigirá a usted para comprender fácilmente a los trabajadores web y sus limitaciones y depuración de los trabajadores web.
Masterización en webworkers
fuente
Creo que la mejor manera de hacer esto es usar un objeto Blob, a continuación puedes ver un ejemplo simple.
fuente
Intenta usar jThread. https://github.com/cheprasov/jThread
fuente
aquí consola:
fuente
https://developer.mozilla.org/es/docs/Web/Guide/Performance/Using_web_workers
fuente
Use mi pequeño complemento https://github.com/zevero/worker-create
fuente
Así que creo que tenemos otra opción genial para esto ahora, gracias a los literales de plantilla en ES6. Eso nos permite prescindir de la función de trabajador adicional (y su alcance extraño) y simplemente escribir el código que está destinado al trabajador como texto multilínea, muy parecido al caso en el que estábamos usando para almacenar texto, pero sin realmente necesitar un documento o DOM hacer eso en. Ejemplo:
Aquí hay una idea del resto de ese enfoque .
Tenga en cuenta que podemos incorporar las dependencias de funciones adicionales que queramos en el trabajador simplemente reuniéndolas en una matriz y ejecutando .toString en cada una de ellas para reducirlas también a cadenas (debería funcionar siempre que sean declaraciones de funciones) y entonces solo anteponiendo eso a la secuencia de comandos. De esa manera, no tenemos que importar scripts que ya podríamos haber incluido en el alcance del código que estamos escribiendo.
El único inconveniente real de esta versión en particular es que los linters no podrán alinear el código del trabajador de servicio (ya que es solo una cadena), lo cual es una ventaja para el "enfoque de la función de trabajador por separado".
fuente
Esto es solo una adición a lo anterior: tengo unas buenas plantillas para probar trabajadores web en jsFiddle. En lugar de Blob, usa la
?js
API jsFiddles :Están disponibles las plantillas normales de trabajador web y trabajador compartido .
fuente
Descubrí que CodePen actualmente no resalta sintaxis
<script>
etiquetas en línea que no lo sontype="text/javascript"
(o que no tienen atributo de tipo).Así que ideé una solución similar pero ligeramente diferente usando bloques etiquetados con
break
, que es la única forma en que puede rescatar de una<script>
etiqueta sin crear una función de envoltura (lo cual es innecesario).fuente
Una versión simple promisificada
Function#callAsWorker
, que toma un thisArg y argumentos (comocall
), y devuelve una promesa:fuente
close()
método para cerrar el enlace de vida de su trabajador web. developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/…close
función está en desuso. Sin embargo, los trabajadores pueden ser despedidos . He agregado eso ahora.Utilizo un código como este, puede definir su mensaje como una función que no sea texto simple, para que el editor pueda resaltar su código y jshint funciona.
fuente
Sí, es posible, lo hice usando archivos Blob y pasando una devolución de llamada
Te mostraré lo que hace una clase que escribí y cómo maneja la ejecución de devoluciones de llamada en segundo plano.
Primero, crea una instancia
GenericWebWorker
con cualquier dato que desee pasar a la devolución de llamada que se ejecutará en elWeb Worker
, que incluye funciones que desea usar, en este caso un número, una fecha y una función llamadablocker
Esta función de bloqueo ejecutará un tiempo infinito durante n milisegundos
y luego lo usas así
fuente
Puede colocar el contenido de su archivo worker.js dentro de los backticks (lo que permite una constante de cadena multilínea) y crear el trabajador a partir de un blob como este:
Esto es útil si por alguna razón no desea tener etiquetas de script separadas para el trabajador.
fuente
Otra solución es simplemente envolver al trabajador en una función, luego crear un blob que invoque la función de esta manera:
fuente
One-liner para ejecutar funciones en trabajadores:
Ejemplo de uso:
fuente