Creating Web Workers From Functions (No File Needed)

So, you want to create a web worker from a function, the problem is all the examples examples show creating a web worker using a separate JavaScript file or from embedded JavaScript source.  There is a way to do it and that is using Blob URLs.  In the example below, I have taken the simple dedicated worker example from mdn and modified it appropriately.
First, we assume that we have a function that we want to serve as the source of the web worker.

var workerScript = function () {
    console.log("starting worker");
    this.onmessage = function(e) {
        console.log('Message received from main script');
        var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
        console.log('Posting message back to main script');
        postMessage(workerResult);
    }
}

Next, we use that function’s source to create the web worker.

// Get the source of the function we want to use and make the source
// where it will be interpreted as an iife.
var workerScriptIifeSource = workerScript.toSource() + "()";
// Create a blob of the script source, specify it as JavaScript.
var workerScriptBlob = new Blob([workerScriptIifeSource],
    {type: 'application/javascript'});
// Create a worker by creating a url from the blob.
var myWorker = new Worker(window.URL.createObjectURL(workerScriptBlob));

See this example in action on jsfiddle here: http://jsfiddle.net/chaddotson/jr5p3L7r/
Notes:

  • The createObjectURL function is experimental according to MDN, so that is a bit of a warning bell.  However, according to caniuse, it is mostly safe across all browsers.
  • This can be used to create shared web workers, but they will not be shareable between tabs or windows.
  • This makes it more difficult, but possible to assemble dependencies for the web worker.
  • This isn’t the officially supported way to create a web worker.
  • I think this approach to creating a worker should be used sparingly, if ever.

 

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply