Podemos utilizar la web trabajador en HTML5 como este:

var worker = new Worker('worker.js');

pero ¿por qué no podemos llamar a una función como esta?

var worker = new Worker(function(){
    //do something
});
  • Usted necesita utilizar una dirección URL, pero algunos navegadores le permiten utilizar una URL BLOB. Consulte este respuesta para un ejemplo.
  • Otro plugin que puede ayudar a que usted es vkThread. Echa un vistazo a http://www.eslinstructor.net/vkthread/ Usted encontrará ejemplos y documentación.
  • Como @Qix dijo en otra de las respuestas de los comentarios, vkThread también está basada en la función.toString, que trae a la incompatibilidad entre navegadores.
InformationsquelleAutor Dozer | 2012-07-06

7 Comentarios

  1. 19

    Esta es la forma en que web los trabajadores están diseñados. Deben tener su propio archivo JS externo y su propio entorno inicializado por ese archivo. Se puede compartir un entorno con su regular global JS espacio para multi-threading conflicto razones.

    Una razón por la que los web workers no permitir el acceso directo a las variables globales es que se requeriría hilo de la sincronización entre los dos ambientes en los que no es algo que está disponible (y podría complicar seriamente las cosas). Web cuando los trabajadores tienen sus propias variables globales, que no se metan con los principales JS hilo, excepto a través de la mensajería de la cola que está correctamente sincronizado con el principal JS hilo.

    Quizás algún día, más avanzada JS programadores serán capaces de utilizar la tradicional rosca de técnicas de sincronización para compartir el acceso a variables comunes, pero por ahora toda la comunicación entre los dos hilos debe ir a través de la cola de mensajes y la web trabajador no puede tener acceso a los principales de Javascript del subproceso de ambiente.

    • de acuerdo, estamos lejos pero han recorrido un largo camino.
    • Creo que el javascript es un Único subproceso.Pero el broswer puede abrir y ejecutar páginas con Multi-threaded. Así que supongo que la web trabajador crear una nueva página(o llame a un nuevo entorno ) y ejecutar la secuencia de comandos en ella? Así que la web trabajador puede llamar un archivo JS externo.
    • eso es básicamente correcto. El principal javascript hilo es de un solo subproceso y mucho código javascript en la web se supone que. En lugar de agregar avanzado hilo de las herramientas de sincronización para permitir genérico multithreading, quienes web diseñada trabajadores decidieron tomar un pequeño paso y permitir que un nuevo hilo, pero SÓLO si se inicializa el propio medio ambiente mundial a través de un nuevo archivo JS y no puede compartir el acceso global con el hilo principal, excepto cuando se sincroniza a través de la cola de mensajes. Esto evita que la variable global de los problemas de sincronización entre hilos.
    • He probado mi conjetura,y fue incorrecta. Ejecutar js en la página hecha por la ventana.open() se construyen bloquear el hilo.
  2. 10

    Esta pregunta se ha hecho antes de, pero por alguna razón, el OP decidió eliminarlo.

    Puedo publicar mi respuesta, en caso de que uno necesita un método para crear una Web trabajador de una función.


    En este post, tres formas en que se muestra para crear una Web trabajador de una cadena arbitraria. En esta respuesta, estoy usando el tercer método, ya que es compatible en todos los ambientes.

    Un archivo de ayuda que se necesita:

    //Worker-helper.js
    self.onmessage = function(e) {
        self.onmessage = null; //Clean-up
        eval(e.data);
    };

    De su Trabajador, este archivo de ayuda se utiliza de la siguiente manera:

    //Create a Web Worker from a function, which fully runs in the scope of a new
    //   Worker
    function spawnWorker(func) {
        //Stringify the code. Example:  (function(){/*logic*/}).call(self);
        var code = '(' + func + ').call(self);';
        var worker = new Worker('Worker-helper.js');
        //Initialise worker
        worker.postMessage(code);
        return worker;
    }
    
    var worker = spawnWorker(function() {
        //This function runs in the context of a separate Worker
        self.onmessage = function(e) {
            //Example: Throw any messages back
            self.postMessage(e.data);
        };
        //etc..
    });
    worker.onmessage = function() {
        //logic ...
    };
    worker.postMessage('Example');

    Tenga en cuenta que los ámbitos que se están estrictamente separados. Las Variables sólo se pueden pasar adelante y hacia atrás utilizando worker.postMessage y worker.onmessage. Todos los mensajes son estructurado clones.

    • Esto supone Function.toString() obras de naciones unidas-eval decompiler, que NO es el caso en ciertos entornos. Usar con precaución!
    • Tu comentario podría ser más útil si se puede nombrar al menos a un común navegador Web donde los Trabajadores son compatibles, pero toString() en una función definida por el usuario no devuelve un funcionalmente equivalente de la fuente por defecto.
    • Los navegadores no son los únicos Javascript entornos. El hecho del asunto es que esto es contra el estándar de la W3C, así como el Ecmascript normas (funciones no deben ser descompilados; entornos en los que el apoyo se proporcionan como una característica adicional sólo con fines de depuración).
    • La función de la serialización no viola ninguna norma (y, ciertamente, no una w3 estándar, desde el W3 no es responsable de la publicación de JS normas…). Específicamente, el actual de la especificación ECMAScript los estados que la representación es dependiente de la implementación. Y en la práctica, todos los modernos motores JavaScript devolver un funcionalmente equivalente fragmento de código JavaScript para funciones definidas por el usuario. Si quieres demostrar tu punto, nombre de un no-esotérico entorno de JavaScript que soporta la Web de los Trabajadores, pero no la serialización de funciones.
    • Me dijo la utilización de funciones en la forma que se sugiere para la web de los trabajadores es un hack y no está cubierto por la norma, por lo que es propenso a pequeños errores o un comportamiento indefinido. Así, no se puede asumir que cada entorno va a apoyar algo que no está en la norma. Yo simplemente estaba señalado.
  3. 3

    Esta respuesta puede ser un poco tarde, pero me escribió una biblioteca para simplificar el uso de los web workers y que podría satisfacer OP necesidad. Check it out: https://github.com/derekchiang/simple-worker

    Se le permite hacer algo como:

    SimpleWorker.run({
      func: intensiveFunction,
      args: [123456],
      success: function(res) {
        //do whatever you want
      },
      error: function(err) {
        //do whatever you want
      }
    })
    • Esto se ve muy similar a la de @vadimk del vkThread post anterior -, obviamente, diferentes proyectos, sin embargo puedo decir que vkThread funciona bien y tiene varios métodos diferentes para su uso.
  4. 1

    Si bien no es óptima y que se ha mencionado en los comentarios, un archivo externo, no es necesario, si tu navegador soporta blobURLs para los Web workers. HTML5Rocks fue el la inspiración para mi código:

    function sample(e)
    {
        postMessage(sample_dependency());
    }
    
    function sample_dependency()
    {
        return "BlobURLs rock!";
    }
    
    var blob = new Blob(["onmessage = " + sample + "\n" + sample_dependency]);
    var blobURL = window.URL.createObjectURL(blob);
    var worker = new Worker(blobURL);
    
    worker.onmessage = function(e)
    {
        console.log(e.data);
    };
    
    worker.postMessage("");

    Advertencias:

    • El blob trabajadores no se van a utilizar correctamente las direcciones Url relativas. HTML5Rocks enlace cubre esto, pero no era parte de la pregunta original.

    • Personas han informado de problemas con el uso de Blob Url de la Web a los Trabajadores. Yo lo he probado con IE11 (lo entregan con FCU), MS Borde 41.16299 (Caída del Creador de Actualización), Firefox 57, y Chrome 62. Ninguna pista en cuanto a soporte técnico de Safari. Los que he probado han funcionado.

    • Tenga en cuenta que la «muestra» y «sample_dependency» las referencias en la nota llamada al constructor implícitamente llamada Function.prototype.toString() como sample.toString() y sample_dependency.toString(), que es muy diferente de llamar a toString(sample) y toString(sample_dependency).

    Publicado esto porque es la primera stackoverflow que surgió cuando la búsqueda de cómo utilizar los Web workers sin solicitar un archivo adicional.

    Echó un vistazo a Zevero la respuesta y el código en su repo parece similar. Si usted prefiere un contenedor limpio, esto es aproximadamente lo que su código no.

    Por último, soy novato aquí, así que cualquier/todas las correcciones son apreciados.

  5. 0

    WebWorkers Essentials

    WebWorkers se ejecutan en un thread independiente, por lo que han sin acceso para el hilo principal, donde se declara ellos (y viceversa). El alcance resultante es aislado y limitado. Por eso, no se puede , por ejemplo, llegar a la catedral de dentro de la persona del trabajador.


    Comunicación con WebWorkers

    Debido a que la comunicación entre hilos es necesario, hay mecanismos para lograrlo. El estándar mecanismo de comunicación es a través de mensajes, el uso de la trabajador.postMessage() función y la trabajador.onMessage(), controlador de eventos.

    Técnicas más avanzadas están disponibles, la participación de sharedArrayBuffers, pero no es mi objetivo a cubrir. Si usted está interesado en ellos, leer aquí.


    De Rosca Funciones

    Eso es lo que la norma nos trae.
    Sin embargo, ES6 nos proporciona suficientes herramientas para implementar un demmand exigible Roscado-Función.

    Ya que se puede construir un Trabajador de una Blob, y su Función se puede convertir en el mismo (utilizando URL.createObjectURL), sólo necesidad de implementar algún tipo de Capa de Comunicación en ambos hilos, para controlar los mensajes para usted, y obtener una interacción natural.

    Promesas de curso, se su amigo, teniendo en cuenta que todo va a pasar de forma asincrónica.

    La aplicación de esta teoría, se puede implementar fácilmente, la situación que usted describe.


    Mi enfoque personal : ParallelFunction

    Me he implementado recientemente y publicado una pequeña biblioteca que hace exactamente lo que usted describe. en menos de 2KB (record).

    Se llama ParallelFunction, y está disponible en github, mecanismo nacional de prevención , y un par de Cdn.

    Como se puede ver, es totalmente coincida con su petición:

    //Your function...
    let calculatePi = new ParallelFunction( function(n){
        //n determines the precision , and in consequence 
        //the computing time to complete      
        var v = 0;
        for(let i=1; i<=n; i+=4) v += ( 1/i ) - ( 1/(i+2) );
        return 4*v;
    });
    
    //Your async call...
    calculatePi(1000000).then( r=> console.log(r) );
    
    //if you are inside an async function you can use await...
    ( async function(){    
        let result = await calculatePi(1000000);
        console.log( result );
    })()
    
    //once you are done with it...
    calculatePi.destroy();

    Después de la inicialización, puede llamar a su función de cuantas veces lo necesite. un Promesa será devuelto al cliente, que resolverá, cuando su función finaliza la ejecución.

    Por el camino, muchas otras Bibliotecas existe.

Dejar respuesta

Please enter your comment!
Please enter your name here