How to pass functions to JavaScript Web Worker

Lachlan picture Lachlan · Aug 11, 2012 · Viewed 20.2k times · Source

I would like to pass a function (or functions) via a postMessage() to a web worker, because I can't refer to regular files.

To kick the web worker off, I am passing an object URL (created from a Blob) to the Worker constructor. Then I am passing a message, but so far no luck putting a function in the message.

The (JSON) message cannot contain functions directly (as stipulated here), and although importScripts is theoretically allowed, I have not had any success using it so far in Chrome or Firefox.

The body of the html file:

<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>

Currently it results in setting the divText value to "importScripts success".

Am I doing something wrong? Is there another way that functions can be passed to web workers? Or is it not possible?

Answer

Lachlan picture Lachlan · Aug 13, 2012

Turns out this method works fine, there was merely a bug in my worker:

var result = greeter("john");

should be

var result = greet("john");

which makes sense - I'm passing the greeter variable to the worker, but there's no reason for it to know the variable name of the object I'm passing.