Dictating the web workers

Web workers are a strong option added to ES6. It allows running long code operation without blocking the user’s thread. It also provides an option to hide the asynchronous operation or network connection behind a worker with no social security rights.

Obedience leads to true freedom. The more we obey revealed truth, the more we become liberated.

James E. Faust

Web workers run on a background thread with a different global context. Since that they have their own execution context they can’t manipulate the DOM, just send or receive messages.

The worker

The worker receives messages from the onmessage method and returns messages to the main thread by the postMessge method.

// worker.js
let count = 0;
onmessage = function (e) {
    setTimeout(()=> {
        count += e.data.add;
        postMessage(count);
    },Math.random()*5000);
};

Main thread

The main thread creates workers with the Worker constructor. Sends a message by the postMessage and receive it with the onmessage method. Note that the code starts with if to detect browsers that do not support web workers. The terminate method will send the worker flowers.

if (window.Worker) {
    var newWorker = new Worker('worker.js');
    newWorker.onmessage = (e) => {
        console.log('Got back ' + e.data);
        newWorker.terminate();
    }
    newWorker.postMessage({ add: 1 });
}

Between the two, messages are copied and not shared. It clones JSON and allows a few additional options like circular references.

Since “with the power comes the responsibility”, my example of a live web worker will be a dictator and his enslaved workers…

Embedded workers

Above I added the web worker by referencing its js file. You can embed web workers by placing them inside a blob:

In the same way, you can use a script tag with no src. That way the script can be used as a data block:

<script type="text/js-worker">
   // worker's code...
</script>
<script>

var blob = new Blob(
    Array.prototype.map.call(
        document.querySelectorAll('script[type=\'text\/js-worker\']'), 
        function (oScript) { 
            return oScript.textContent; 
        }
    ),
    {type: 'text/javascript'});
document.worker = new Worker(window.URL.createObjectURL(blob));
...
...
</script>

To summarize it up: Until the day other will work for you, the only thin you can do is to force web workers do it for you 🙂