Me gustaría pasar una función (o funciones) a través de un postMessage() a una web trabajador, porque no puedo consulte los archivos regulares.

A patear la web trabajador fuera, estoy pasando un objeto URL (creado a partir de un Blob) a la Worker constructor. Entonces yo estoy pasando un mensaje, pero hasta el momento no hay suerte poniendo una función en el mensaje.

La (JSON) mensaje no puede contener funciones directamente (tal como se estipula aquí), y aunque importScripts teóricamente es permitido, no he tenido ningún éxito con ella hasta el momento en Chrome o Firefox.

El cuerpo del archivo html:

<div id="divText">1234</div>
<script>
    var greeter = function greet(name) {
        return "hello " + name;
    };
    function webWorkerWorker() {
        self.postMessage("started1");
        self.onmessage = function(event) {
            importScripts(event.data.content);
            self.postMessage("importScripts success");
            var result = greeter("john");
            self.postMessage(result);
        };
    }
    var functionBody = mylib.extractFunctionBody(webWorkerWorker);
    var functionBlob = mylib.createBlob([functionBody]);
    var functionUrl = mylib.createObjectURL(functionBlob);

    var functionBody2 = mylib.extractFunctionBody(greeter);
    var functionBlob2 = mylib.createBlob([greeter]);
    var functionUrl2 = mylib.createObjectURL(functionBlob2);

    var worker = new Worker(functionUrl);
    worker.onmessage = function(event) {
        document.getElementById("divText").innerHTML = event.data;
    }
    worker.postMessage({
                type: "init",
                content: functionUrl2
            });
</script>

Actualmente resulta en la creación de la divText el valor de la «importScripts éxito».

Estoy haciendo algo mal? Hay otra manera de que las funciones se pueden pasar a la web de los trabajadores? O no es posible?

Hola se puede proporcionar a su «mylib» funciones está utilizando aquí..Gracias

OriginalEl autor Lachlan | 2012-08-10

3 Comentarios

  1. 5

    Resulta este método funciona bien, no fue simplemente un error en mi trabajo:

    var result = greeter("john");

    debe ser

    var result = greet("john");

    que tiene sentido – lo estoy pasando a la interfaz gráfica de la variable para el trabajador, pero no hay ninguna razón para que se sepa el nombre de la variable del objeto que estoy pasando.

    OriginalEl autor Lachlan

  2. 3

    Para aquellos que están buscando para obtener más genérico respuesta:
    aquí es un plugin, que permite ejecutar cualquier función de su código javascript en un hilo.

    http://www.eslinstructor.net/vkthread/

    Consideran como «outsourcing». Se pasa de cualquier función para el plugin, como un argumento y obtener como resultado de devolución de llamada. Usted también puede «contratar» métodos del objeto, la función con dependecies, función anónima y lambda.

    Disfrutar.

    –Vadim

    ¿Cuál es la licencia en vkthread? Se parece a un pequeño y conveniente de la biblioteca. Encantaría usarlo pero no puedo construir cosas dependen de él sin saber la licencia.
    Licencia MIT, lo que quiere decir libre para todos, sin restricciones.

    OriginalEl autor vadimk

  3. 0

    Sí, por supuesto que es posible, yo implementado

    Esta es una promesa que se va a ejecutar el genérico trabajador

    /*
    @data.context, The context where the callback functions arguments are, ex: window
    @data.callback, ["fn_name1", "fn_name2", function (fn1, fn2) {}]
    The callback will be executed, and you can pass other functions to that cb
    @worker_url string url of generic web worker
    */
    function genericWorker(worker_url, data) {
    return new Promise(function (resolve, reject) {
    if (!data.callback || !Array.isArray(data.callback))
    return reject("Invalid data")
    var callback = data.callback.pop()
    var functions = data.callback
    var context = data.context
    if (!worker_url)
    return reject("Worker_url is undefined")
    if (!callback)
    return reject("A callback was expected")
    if (functions.length>0 && !context)
    return reject("context is undefined")
    callback = fn_string(callback) //Callback to be executed
    functions = functions.map((fn_name)=> { return fn_string( context[fn_name] ) })
    var worker = new Worker(worker_url)
    worker.postMessage({ callback: callback, functions: functions })
    worker.addEventListener('error', function(error){
    return reject(error.message)
    })
    worker.addEventListener('message', function(e) {
    resolve(e.data)
    worker.terminate()
    }, false)
    //From function to string, with its name, arguments and its body
    function fn_string (fn) {
    var name = fn.name
    fn = fn.toString()
    return {
    name: name,
    args: fn.substring(fn.indexOf("(") + 1, fn.indexOf(")")),
    body: fn.substring(fn.indexOf("{") + 1, fn.lastIndexOf("}"))
    }
    }
    })
    }

    El genérico trabajador archivo worker_for_anything.js

    self.addEventListener('message', function(e) {    
    var worker_functions = {} //Functions used by callback
    var args = [] //Arguments of the callback
    for (fn of e.data.functions) {
    worker_functions[fn.name] = new Function(fn.args, fn.body)
    args.push(fn.name)
    }
    var callback = new Function( e.data.callback.args, e.data.callback.body) //Callback passed and ready to be executed    
    args = args.map((fn_name) => { return worker_functions[fn_name] }) //FUnctions loaded as arguments
    var result = callback.apply(null, args) //executing callback with function arguments
    self.postMessage( result )
    }, false)

    A usarlo 🙂

    var data = {
    context: window, //the context of the functions passed, ex: window for blockCpu
    callback: ["blockCpu", function (bla) {
    bla(7000) //blocking for 7000 ms
    return "bla" //This return is catched in the promise
    }]
    }
    genericWorker("/worker_for_anything.js", data)
    .then(function (result){
    console.log("result", result)
    }).catch((error)=> { console.log(error) })
    //random blocking function
    function blockCpu(ms) {
    var now = new Date().getTime();
    var result = 0
    while(true) {
    result += Math.random() * Math.random();
    if (new Date().getTime() > now +ms)
    return;
    }   
    }

    OriginalEl autor Fernando Carvajal

Dejar respuesta

Please enter your comment!
Please enter your name here