Created
May 11, 2018 12:50
-
-
Save therightstuff/eb415798b0e30866fe85d66af68969cf to your computer and use it in GitHub Desktop.
Web Worker callback design pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ensure window object available | |
var window = self; | |
self.addEventListener('message', function (e) { | |
var payload = e.data; | |
var result = null; | |
var err = null; | |
switch (payload.cmd) { | |
case 'sampleCommand': | |
console.log("worker processing sampleCommand"); | |
result = 'example result ' + payload.data.echo; | |
break; | |
default: | |
console.log("worker not processing unknown command"); | |
err = 'Unknown command ' + payload.cmd; | |
}; | |
// return result to main thread | |
self.postMessage({ callId: payload.callId, result: result, error: err }); | |
}, false); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var workers = {}; | |
workers.nextCallId = 0; | |
workers.callbacks = {}; | |
// handle worker responses | |
workers.handler = function (e) { | |
if (!workers.callbacks[e.data.callId]) { | |
console.info('worker ' + e.data.callId + ' callback not defined on ' + (e.data.error ? 'error' : 'success')); | |
} else { | |
if (e.data.error) { | |
// log error | |
console.error('worker ' + e.data.callId + ' callback on error'); | |
console.error('worker ' + e.data.callId + ' error: ' + e.data.error); | |
workers.callbacks[e.data.callId](e.data.error); | |
} else { | |
// send data to callback function | |
console.info('worker ' + e.data.callId + ' callback on success'); | |
workers.callbacks[e.data.callId](null, e.data.result); | |
} | |
// remove callback reference | |
workers.callbacks[e.data.callId] = null; | |
} | |
}; | |
myExampleWorker = new Worker('exampleWorker.js'); | |
myExampleWorker.addEventListener('message', workers.handler, false); | |
// wrapper for postMessage | |
workers.post = function (worker, cmd, data, cb) { | |
var callId = workers.nextCallId++; | |
// register callback function | |
workers.callbacks[callId] = cb; | |
// post data to worker | |
worker.postMessage({cmd:cmd, callId: callId, data:data}); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<script src="manager.js"></script> | |
<script lang="javascript"> | |
function logResult(command, result){ | |
document.getElementById("logs").value += command + ": " + result + '\n'; | |
} | |
function logError(command, error){ | |
document.getElementById("logs").value += command + " ERROR: " + error + '\n'; | |
} | |
function test1() { | |
// works, result is "example result works" | |
workers.post(myExampleWorker, 'sampleCommand', { echo: 'works' }, function (err, result) { | |
if (err){ | |
logError('sampleCommand', err); | |
} else { | |
logResult('sampleCommand', result); | |
} | |
}); | |
} | |
function test2() { | |
// works with no callback | |
workers.post(myExampleWorker, 'sampleCommand', { echo: 'works with no callback' }); | |
} | |
function test3() { | |
// fails with no callback | |
workers.post(myExampleWorker, 'invalidCommand', { echo: 'fails with no callback' }); | |
} | |
function test4() { | |
// fails with bad command | |
workers.post(myExampleWorker, 'invalidCommand', null, function (err, result) { | |
if (err){ | |
logError('invalidCommand', err); | |
} else { | |
logResult('invalidCommand', result); | |
} | |
}); | |
} | |
</script> | |
</head> | |
<body> | |
<button onclick="test1()">Success</button> | |
<button onclick="test2()">Success with no callback</button> | |
<button onclick="test3()">Failure with no callback</button> | |
<button onclick="test4()">Failure with callback</button> | |
<hr /> | |
<textarea id="logs" rows="10" cols="80"></textarea> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment