Reading about web workers I stumbled across this example from mdn. The worker.js
is just once simple function.
So when we post a message to the worker the onmessage
part is then started by the worker. In the simple example the worker just multiplies two numbers. But what if I want a worker that can also add, divide etc? Do I need to create a new worker file (e.g. worker_add.js
) for each function I want my worker to run? Or what is the cleaner way to deal with this?
I was thinking of having a string posted as first argument to the worker
myWorker.postMessage(["method", arg1, arg2]);
and then in my worker I have if/else
conditionals which check if the string matches and then execute different code.
importScripts('emscripten.js')
onmessage = function(e) {
console.log('Message received from main script.');
if (e.data[0] == "method1")
{
Module.method1(e.data[1].byteOffset, e.data[2]);
postMessage(e.data[1]);
}
else if (e.data[0] == "method2")
{
var ret= Module.method2();
postMessage(ret);
}
console.log('Posting message back to main script');
}
In the spirit of Emil's answer I found an example on html5rocks. I feel like this is slightly cleaner than Emil's answer.
The main script looks like this
<button onclick="sayHI()">Say HI</button>
<button onclick="unknownCmd()">Send unknown command</button>
<button onclick="stop()">Stop worker</button>
<output id="result"></output>
<script>
function sayHI() {
worker.postMessage({'cmd': 'start', 'msg': 'Hi'});
}
function stop() {
// worker.terminate() from this script would also stop the worker.
worker.postMessage({'cmd': 'stop', 'msg': 'Bye'});
}
function unknownCmd() {
worker.postMessage({'cmd': 'foobard', 'msg': '???'});
}
var worker = new Worker('doWork2.js');
worker.addEventListener('message', function(e) {
document.getElementById('result').textContent = e.data;
}, false);
</script>
and the worker doWork2.js
like this:
self.addEventListener('message', function(e) {
var data = e.data;
switch (data.cmd) {
case 'start':
self.postMessage('WORKER STARTED: ' + data.msg);
break;
case 'stop':
self.postMessage('WORKER STOPPED: ' + data.msg +
'. (buttons will no longer work)');
self.close(); // Terminates the worker.
break;
default:
self.postMessage('Unknown command: ' + data.msg);
};
}, false);