Post

Web Workers

This page will demonstrate how to setup Web Workers, dispatch tasks to workers, and send messages/results from workers to the main thread.

  1. HTML Page
  2. Worker Code
  3. Example Output

HTML Page

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!DOCTYPE html>
<html>
<head>
	<title>Web Workers</title>
</head>
<body>
	<script type="text/javascript">
		console.log('Creating Web Worker(s)...');

		// Handler function for when a Worker sends a message
		const workerOnMessageHandler = ({ data }) => {
			let { workerId, action, outputData} = data;

			if (action === 'print-data') {
				console.log(...outputData);
			} else if (action === 'randomNumber') {
				console.log(`Random Number Results from Worker ${workerId}:`, outputData);
			}
		}

		// How many Workers we want to create
		const totalWorkers = 4;
		const randomNumberRange = 1000;

		// List to store our Workers
		let workerList = [];

		// Create Workers
		for (let i = 0; i < totalWorkers; ++i) {
			// Create a new random number Worker
			let workerObj = new Worker('worker-randomNumber.js');

			// Set the callback for when the Worker posts a message
			workerObj.onmessage = workerOnMessageHandler;

			// Add the Worker to the Worker list
			workerList.push({ workerId: i, action: 'randomNumber', workerObj })
		}

		// Send a task to each Worker
		for (let i = 0; i < workerList.length; ++i) {
			workerList[i].workerObj.postMessage({
				workerId: workerList[i].workerId,
				action: 'randomNumber',
				inputData: randomNumberRange
			});
		}
	</script>
</body>
</html>
  • The postMessage function calls the function stored in self.onmessage inside the Web Worker (see below).


Worker Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const printMessage = (workerId, ...msg) => {
	self.postMessage({
		workerId,
		action: 'print-data',
		outputData: msg
	});
}

const calculations = (inputData) => {
	return Math.round(Math.random()*inputData);
}

self.onmessage = ({ data }) => {
	let { workerId, action, inputData } = data;

	// Print the string to the screen
	printMessage(workerId, `Worker (${workerId}) Received Data:`, inputData);

	// Calculate results
	let result = calculations(inputData);

	// Return results
	self.postMessage({ workerId, action, outputData: result });
}
  • The postMessage function here calls the function stored in workerObj.onmessage that was set for this Worker in the main thread.

Example Output

  • NOTE there is no guarantee that the tasks will finish in any sort of order.

  • The order will very likely change every time the program is run.
This post is licensed under CC BY 4.0 by the author.