To use a dedicated Web worker, we ususally follow these steps:
This is the example adapted from [1]:
Source of prime.js. It is used to calculate the prime number in the background:
self.onmessage = function(event) { findPrime(); } function findPrime() { var n = 1; var prime; while (true) { n++; prime = true; for (var i = 2; i <= Math.sqrt(n); i++) if (n % i == 0) { prime = false; break; } if (prime) postMessage(n); } }
Source of findPrime.html. It is used to start and stop the Web worker thread:
<!DOCTYPE html> <html> <head> <title>Find a Prime</title> </head> <body> <form> <label for="prime">The largest prime number: </label><input type="text" id="prime" disabled/> <input type="button" value="Start" onclick="startFind()"/> <input type="button" value="End" onclick="stopFind()"/> </form> <script type="text/javascript"> var worker; function startFind() { worker = new Worker('prime.js'); worker.onmessage = function(event) { document.getElementById('prime').value = event.data; } worker.postMessage('Start'); } function stopFind() { worker.terminate(); } </script> </body> </html>
The screenshot of the Webpage:
To use a shared Web worker is similar to the dedicated Web worker, with the following differences:
The source code of getServerTime.html:
<!DOCTYPE html> <html> <head> <title>Get Server Time</title> </head> <body> <form> <label for="prime">The server's time: </label><input type="text" id="time" disabled/> <input type="button" value="Get time" onclick="getTime()"/> </form> <script type="text/javascript"> function getTime() { var worker = new SharedWorker('gettimeShared.js'); worker.port.onmessage = function(event) { document.getElementById('time').value = event.data; } worker.port.postMessage('Start'); } </script> </body> </html>
The source code of gettimeShared.js:
self.onconnect = function(event) { var port = event.ports[0]; var xhr = new XMLHttpRequest(); xhr.open('get', 'gettime.php', true); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if ((xhr.status >= 200 && xhr.status<=299) || xhr.status == 304) port.postMessage(xhr.responseText); else alert('Error in ajax communication: ' + xhr.statusText); } }; xhr.send(null); };
The source code of gettime.php:
<?php date_default_timezone_set('America/New_York'); echo date('M d Y, h:i:s A'); ?>
The screenshot of the Webpage:
It is possible to include the source code of the Web worker in the same HTML Web page. But we need to follow the following steps:
The source code of findPrimev2.html:
<!DOCTYPE html> <html> <head> <title>Find a Prime</title> </head> <body> <script id="worker" type="text/js-worker"> self.onmessage = function(event) { findPrime(); } function findPrime() { var n = 1; var prime; while (true) { n++; prime = true; for (var i = 2; i <= Math.sqrt(n); i++) if (n % i == 0) { prime = false; break; } if (prime) postMessage(n); } } </script> <form> <label for="prime">The largest prime number: </label><input type="text" id="prime" disabled/> <input type="button" value="Start" onclick="startFind()"/> <input type="button" value="End" onclick="stopFind()"/> </form> <script type="text/javascript"> var worker; function startFind() { var script = document.getElementById('worker').textContent; var blob = new Blob([script]); worker = new Worker(window.URL.createObjectURL(blob)); worker.onmessage = function(event) { document.getElementById('prime').value = event.data; } worker.postMessage('Start'); } function stopFind() { worker.terminate(); } </script> </body> </html>
When passing arguments to/from the Web worker thread, the data are copied, which takes some time. Firefox 18 and Chrome 17 support passing data with transferrable objects to save the overhead of copying, which is similar to passing by reference in C++. However, the ownership of the transferrable objects is also transferred from one thread to another thread. Thus, the transferrable object is not available any more in the original thread's context.
Below are the two examples: the first one uses transferrable objects, the second one passes a regular array object to the Web worker thread:
<!DOCTYPE html> <html> <head> <title>Find Sum</title> </head> <body> <script id="worker" type="text/js-worker"> self.onmessage = function(event) { var array = new Uint8Array(event.data); var sum = 0; for (var i = 0; i < array.length; i++) sum += array[i]; postMessage(sum); } </script> <form> <label for="prime">The sum: </label><input type="text" id="sum" disabled/> <input type="button" value="SUM" onclick="sumUp()"/> </form> <script type="text/javascript"> function sumUp() { var script = document.getElementById('worker').textContent; var blob = new Blob([script], { type: "text/javascript"}); var array = new Uint8Array(1024 * 1024 * 32); // 32 MB for (var i = 0; i < array.length; i++) array[i] = 1; var worker = new Worker(window.URL.createObjectURL(blob)); worker.onmessage = function(event) { document.getElementById('sum').value = event.data; } worker.postMessage(array.buffer, [array.buffer]); alert(array.length); // shows 0 } function stopFind() { worker.terminate(); } </script> </body> </html>
<!DOCTYPE html> <html> <head> <title>Find Sum</title> </head> <body> <script id="worker" type="text/js-worker"> self.onmessage = function(event) { //var array = new Uint8Array(event.data); var array = event.data; var sum = 0; for (var i = 0; i < array.length; i++) sum += array[i]; postMessage(sum); } </script> <form> <label for="prime">The sum: </label><input type="text" id="sum" disabled/> <input type="button" value="SUM" onclick="sumUp()"/> </form> <script type="text/javascript"> function sumUp() { var script = document.getElementById('worker').textContent; var blob = new Blob([script], { type: "text/javascript"}); var array = new Array(1024 * 1024 * 16); // 16 MB. If I use 32 MB, the program will abort. for (var i = 0; i < array.length; i++) array[i] = 1; var worker = new Worker(window.URL.createObjectURL(blob)); worker.onmessage = function(event) { document.getElementById('sum').value = event.data; } worker.postMessage(array); alert(array.length); //shows 16777216 } function stopFind() { worker.terminate(); } </script> </body> </html>
Attributes:
Methods:
Event handler:
Methods:
Event handler:
Attributes:
Event handler:
Methods:
Event handler:
Attributes:
Methods: