Web Workers: Running JavaScript on the Background
This tutorial demonstrates how you can create and terminate a Web worker, handle errors, and send messages between workers.
Warm-up
Become familiar with the Web Workers API basics by learning about:
-
Creating a Web Worker and Handling Errors
Create and execute a Web worker and a subworker, and handle worker-related errors.
-
Sending Messages between Web Workers
Send messages between host workers and subworkers.
Creating a Web Worker and Handling Errors
Learning how to create Web workers is a useful resource management skill:
- To create and execute a Web worker:
-
Create JavaScript code for a simple Boolean operation:
var n = 1; index: while (true) { n += 1; for (var i = 2; i <= Math.sqrt(n); i += 1) if (n % i == 0) continue index; postMessage(n); }
This JavaScript operation delivers the calculated value of the Math.sqrt(n) function to the postMessage() method. It cannot be used for continuous posting of the Boolean operation.
-
Create a Web worker to be activated in the background. The JavaScript URL defining the worker needs to be delivered when creating the worker object:
<button type="button" onclick="workerStart()">Start</button> <button type="button" onclick="worker.terminate()">Stop</button> <output></output>
<script> var worker = new Worker("worker3.js"); function workerStart() { worker.onmessage = function(e) { document.querySelector("output").textContent = e.data; }; } </script>
When the Start button is clicked, message data is received from the worker and displayed in the <output> element. When the Stop button is clicked, the worker is terminated.
Simple operations can be sufficiently handled with a single worker, however, in order to execute a more complex operations, more workers are needed.
-
- To create a subworker, use the importScripts() method:
importScripts('worker1.js'); importScripts('worker1.js', 'worker2.js');
The subworker creates its own independent thread, and is activated in it, so it has the same restrictions as a host worker. This means that communication between subworkers is impossible, but a host worker can communicate with subworkers within the same object.
- To handle errors:
-
If an error occurs when the worker is being executed, the onerror() event is triggered. It takes filename, lineno, and message attributes, and displays an error message:
worker.onerror = function(e) { document.querySelectorAll("output")[1].textContent = ['filename: ', e.filename, ' lineno: ', e.lineno, ' error: ', e.message].join(' '); };
-
The addEventListener can be used instead of the onerror event to detect errors and display an error message:
function errorMessage(e) { document.querySelectorAll("output")[1].textContent = ['filename: ', e.filename, ' lineno: ', e.lineno, ' error: ', e.message].join(' '); } worker.addEventListener('error', errorMessage, false);
-
Sending Messages between Web Workers
Learning how to send messages between Web workers is a useful resource management skill:
- Send a message in one of the following ways:
-
Use the postMessage() method to send a "Hello" message to a Web worker:
var worker = new Worker('worker1.js'); worker.postMessage("Hello");
-
Use the JSON format to send the message:
var worker = new Worker('worker2.js'); worker.postMessage( { a: "Hello", b: "Tizen" });
-
-
Receive a message in one of the following ways:
-
Use the onMessage event handler to respond to receiving a message:
worker.onmessage = function(e) { alert(e.data); };
-
Use the addEventListener() method to listen to the event of receiving a message:
worker.addEventListener("message", function(e) { alert(e.data); }, false);
-
-
Use the workers to execute threads:
-
Use worker1.js:
self.onmessage = function(e) { self.postMessage("You say: " + e.data); };
-
Use worker2.js:
self.onmessage = function(e) { var b = e.data.b; if (b === "Tizen") { self.postMessage(e.data.b + " say: " + e.data.a); } else { self.postMessage("You say: " + e.data.a); } };
The postMessage() method can also execute the worker and respond to a message simultaneously.
-
Source Code
For the complete source code related to this use case, see the following files: