Web Workers
NB: This is not about web developers or software engineers; though there are some similarities in behaviors of these two.
Web Workers are new set of APIs introduced with HTML5 specifications. This enables web pages to run (long running) scripts in the background threads. Web workers brings following advantage in HTML/ Java Script world.
- Running tasks (specially time consuming jobs or repeated jobs like status check etc) behind the scene while UI is interactive to the users.
- A task parallel programming approach which enable the developers to make use of increasing usage of multi-core processors in the PC/laptop world.
- Not implemented through loops; but uses message notification mechanism to communicate to and from the main UI thread.
Spawning a working in JavaScript is simple; just need to call the "Worker()" constructor with a URI of script to execute in the worker thread.
var worker = new Worker("worker.js");
There are two main event handlers that we need to understand to use a web worker
- onmessage event handler: The message communication between main UI thread (web page) and worker is possible through this API. Main UI thread attaches a local callback method to listen to 'onmessage' event. Same way a callback method is attached to 'onmessage' event inside the worker thread. When postMessage is invoked from main thread to the worker thread, event handler inside the worker thread gets notification. When worker thread is ready to pass data back to the main thread, it calls postMessage which triggers the attached event handler on the main UI thread.
// Inside main UI thread (HTML page)
worker.addEventListener('message', function(e) {
doTask(e.data);
}, false);
//Inside worker.js
self.addEventListener('message', function(e) {
doTask(e.data);
}, false); - onerror event handler: Similar to onmessage handler; onerror handler watch for errors on both side. We don't have to explicitly invoke this event; an error inside the thread will cause the onerror event to be triggered.
// code inside main UI thread.
// Triggers message handler inside the thread.
worker.postMessage('message");
// code inside worker.js
// Triggers
message handler in the main ui
self.postMessage(result);
And finally, you can free up the resource by calling
self.close()
self.destroy()
Here is a demo which uses multiple workers to do time consuming tasks. After completing tasks from all workers, main UI can do next steps based on the logic. Full source code is given below:
Worker.html.
<html>
<head>
<title>Multi threading sample</title>
</head>
<body>
<div id="error" style="color: red;"></div>
<br/>
Progress:
<div id="progress"></div>
<br />
Final:
<div id="result"></div>
<script type="text/javascript">
var totalWorkers = 10;
var results = [];
var onMessage = function(e) {
results.push(e.data);
document.getElementById('progress').innerHTML += e.data + ', ';
if (results.length == totalWorkers) {
jobCompletedCallback();
}
};
var onError = function(e) {
document.getElementById('error').textContent = [
'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message].join('');
};
for(var i=0; i<totalWorkers; i++) {
var worker = new Worker("worker.js");
worker.addEventListener('message', onMessage, false);
worker.addEventListener('error', onError, false);
worker.postMessage(i);
}
function jobCompletedCallback() {
document.getElementById('result').innerHTML = results.join('->');
}
</script>
</body>
</html>
Worker.js
self.addEventListener('message', function(e) {
doTask(e.data);
}, false);
self.addEventListener('error', function(e) {
doTask(e.data);
}, false);
function doTask(data) {
//delay for random seconds
var rnd = Math.floor((Math.random() * 10)%10*1000);
//self.postMessage(data+'->'+rnd+'* ');
setTimeout(function() {onTaskComplete(data)}, rnd);
}
function onTaskComplete(result) {
//Uncomment below line to see the exception handling scenario.
//var a = b;
self.postMessage(result);
//self.close();
}
Browser compatibility: Following browsers implemented Worker APIs.
- Chrome 3
- FireFox 3.5
- Safari 4
- Opera 10.6
References:
Note: Imported from my site https://sites.google.com/site/dhtmlexperiments/blogs/webworkers dated Mar 24, 2011
Comments
Post a Comment