Web Workers - Quick JavaScript Interview Questions (2015)

Quick JavaScript Interview Questions (2015)

Chapter 10. Web Workers

Q. What is a Web Worker?
ANSWER
Web Workers are new HTML5 feature to achieve concurrency in JavaScript execution in web application. A web worker is JavaScript file which run in the background of the browser without impacting the page performance. This helps in resolve the age old problem “Un responsive script alert box”. Generally these workers can be used for extensive computation purpose.

Q. How to detect Web Worker is supported by browser? ANSWER
We can check the support of Web Worker in a browser by validating the Worker property is present in the window object. Code for checking Web Worker support is as follows:

<!DOCTYPE html>
<html>
<head lang="en">

<title>Web Worker</title>
</head>
<body>

<script>
var isWorkerSupported = window.Worker ? true : false; console.log("Is Web Worker Supported:

"+isWorkerSupported);
</script>
</body>
</html>
In the previous code isWorkerSupported variable can contain TRUE or FALSE value based on the existence of Worker property inside window object. The following screenshot shows the output of above code in chrome console.

Q. What is a dedicated worker?
ANSWER
A dedicated worker is only accessible by the calling script. A dedicated worker object can be created using worker constructor. Syntax for creating a new dedicated worker is listed below.

var aDedicatedWorker = new Worker("script.js")
The parameter inside the Worker object is the JavaScript file which will run as worker in the background of the browser.

Q. What is a shared worker?
ANSWER
A Shared Worker can be accessed by multiple scripts. A shared worker is accessible by different window, iframe and by other worker having same origin. Syntax for creating a new dedicated worker is as follows.

var aSharedWorker = new SharedWorker("script.js")
The parameter inside the Worker object is the JavaScript file which will run as shared worker in the background of the browser.
Q. Develop a dedicated worker to display the time?
ANSWER

Let’s create the time worker in dateWorker.js file and we can call this worker in dateWorkerDemo.html file. The following code shows the content of dateWorker.js file which listens to the messages and posts the current time in every second.

self .addEventListener("message",function(event){ setInterval(function(){
var time = new Date();
self.postMessage({

hour :time.getHours(),
minute: time.getMinutes(),
second: time.getSeconds()

});
},1000

);
});

The following code shows the content of dateWorkerDemo.html containing creation of worker instance and listening to worker response.

<!DOCTYPE html>
<html>
<head lang="en">

< meta charset="UTF-8">
<title>Time Web Worker Demo</title> </head>
<body>
<h1 id="resultContainer"></h1>
<button id="timeButton">Get Time</button>

< script>
var dateWorker = new Worker("dateWorker.js"),
resultContainer = document.getElementById("resultContainer"), timeButton = document.getElementById("timeButton");

timeButton .addEventListener("click",function(){
dateWorker.postMessage(null);
});
dateWorker.addEventListener("message",function(workerEvent){ var responseData = workerEvent.data,
hour = responseData.hour,
minute = responseData.minute,
second = responseData.second;
resultContainer.innerText = "HOUR: "+hour +

" MINUTE: " +minute +" SECOND: "+second; });
</script>
</body>
</html>

The output of the preceding code shown in following screenshot with hour, minute and second is displayed from the worker response messages.

Q. Develop a dedicated worker to find square of a number? ANSWER
The definition of square worker is present in doSquareWorker.js file and listens to message and generates the square of number. The square worker is instantiated in squareWorkerDemo.html file which listens to the response from the square worker and prints it in browser.The code content of doSquareWorker.js file are as follows.

self .addEventListener("message",function(event){
var inputData = event.data,
inputNumber = parseInt(inputData.number,10),
squareResult = Math.pow(inputNumber,2);

self.postMessage({result

:squareResult});
});
The squareWorkerDemo.html file has the following code.

<!DOCTYPE html>
<html>
<head lang="en">

< meta charset="UTF-8">
<title>Square Web Worker Demo</title> </head>
<body>

<h1 id="resultContainer"></h1>

< input type="number" id="inputNumber" placeholder="Enter a number" value="5">
<button id="squareButton"> SQUARE</button>

< script>
var squareWorker = new Worker("doSquareWorker.js"), resultContainer = document.getElementById("resultContainer"), squareButton = document.getElementById("squareButton"), inputNumber=document.getElementById("inputNumber");

squareButton .addEventListener("click",function(){ squareWorker.postMessage({number:inputNumber.value});
});

squareWorker.addEventListener("message",function(workerEvent){ var responseData = workerEvent.data,
squareResult= responseData.result;
resultContainer.innerText = squareResult;
});

</ script>
</body>
</html>

The output of the preceding code shown in following screenshot with square of a number is displayed from the worker response messages.

Q. How to define an inline web worker? Demonstrate an inline worker for multiplying 2 numbers?
ANSWER
An inline web worker can be defined inside a HTML markup using <script> tag with type attribute having value javascript/worker. Syntax:

< script type="javascript/worker">
//JavaScript Code for defining a worker
</script>

Example:
The inlineWorkerDemo.html file contains the code for defining multiplication worker which listens to the messages and calculates the multiplication and post the response. The listener to the multiply worker extracts the result and renders in the browser. The following code shows the content of inlineWorkerDemo.html file.

<!DOCTYPE html>
<html>
<head lang="en">

< meta charset="UTF-8">
<title>Inline Web Worker Demo</title>
</head>
<body>
<h1 id="resultContainer"></h1>
<input type="number" id="number1" value="8" placeholder="Enter first number"> <input type="number" id="number2" value="10" placeholder="Enter second number">
<button id="multiplyButton">Multiply</button>
<script id="multiplyWorker" type="javascript/worker">
self.addEventListener("message",function(event){
var requestData = event.data,
number1 = requestData.number1,
number2 = requestData.number2,
multiplyResult = number1 * number2;
self.postMessage({result:multiplyResult});
});
</script>
<script>
var textContent = document.querySelector('#multiplyWorker').textContent, workerBlob = new Blob([textContent]),
workerURL = window.URL.createObjectURL(workerBlob), multiplyWorker = new Worker(workerURL),
resultContainer = document.getElementById("resultContainer"), multiplyButton = document.getElementById("multiplyButton"), number1 = document.getElementById("number1"),
number2 = document.getElementById("number2");
multiplyButton.addEventListener("click", function () {
multiplyWorker.postMessage({
number1:parseInt(number1.value,10),
number2: parseInt(number2.value,10)
});
});
multiplyWorker.addEventListener("message", function (workerEvent) {
var responseData = workerEvent.data,
result = responseData.result;
resultContainer.innerText = "Result: " + result;
});
</script>
</body>
</html>

User can input two numbers in the text box and press the multiply button. The multiply worker calculate the multiplication and result is rendered in the browser. The outputs of the preceding code are rendered as following screenshot.

Q. How to handle error in web worker?
ANSWER
We can throw error using throw keyword from the web worker. A callback method can be attached to the error event to handle the generated error. The positiveNoSqaureWorkerDemo.html file contains a worker which takes only positive number as input. If a negative number is passed it throws an error. The code content of this file is as follows.

<!DOCTYPE html>
<html>
<head lang="en">

< meta charset="UTF-8">
<title>Web Worker Error Handler Demo</title>
</head>
<body>
<h1 id="resultContainer"></h1>
<input type="number" id="number1" value="-4" placeholder="Enter a number"> <button id="squareResult">Square</button>
<script id="squareWorker" type="javascript/worker">
self.addEventListener("message",function(event){
var requestData = event.data,
number1 = requestData.number1,
squareResult = 0;
if(number1>0) {
squareResult = number1 * number1
self.postMessage({result:squareResult});
} else{
//For negative number throw error
throw "It is a negative number.Please supply a positive number."; }
});
</script>
<script>
var textContent = document.querySelector('#squareWorker').textContent,
workerBlob = new Blob([textContent]),
workerURL = window.URL.createObjectURL(workerBlob),
squareWorker = new Worker(workerURL),
resultContainer = document.getElementById("resultContainer"),
squareResult = document.getElementById("squareResult"),
number1 = document.getElementById("number1"),
number2 = document.getElementById("number2");
squareResult.addEventListener("click", function () {
squareWorker.postMessage({
number1:parseInt(number1.value,10)
});
});
//Success Handler for the worker
squareWorker.addEventListener("message", function (workerEvent) { var responseData = workerEvent.data,
result = responseData.result;
resultContainer.innerText = "Result: " + result;
});
//Error Handler for the worker
squareWorker.addEventListener('error', function(workerErrorEvent){ resultContainer.innerText = "Error: " + workerErrorEvent.message; }, false);
</script>
</body>
</html>

The output of the above code is rendered as following screenshot rendering the error message in the browser.

Q. How to import an external script in web worker? Demonstrate it with an example?
ANSWER
To import external script inside a web worker we need to use importScripts() method with a file name as input parameter. To demonstrate import script functionality we have created 3 files greatest-number-script.js, numberWorker.js,
numberWorkerDemo.html file. The following screenshot shows these files.

The greatest-number-script.js is the external script that we need to import it to our web worker. It has a single method
findGreatestNumber() method to find out a bigger number among two supplied numbers. The following code shows the content of greatest-number-script.js file.

var findGreatestNumber = function(number1,number2){
return number1>number2 ? number1 : number2;
};

The numberWorker.js file contains the code for importing the external script inside the web worker message listener callback method. The following code shows the content of
numberWorker.js file.

self .addEventListener("message",function(event){
var numberWorker = self.importScripts('greatest-number-script.js'); var requestData = event.data,

number1 = requestData.number1,
number2 = requestData.number2,


greatestNumber = findGreatestNumber(number1,number2); self.postMessage({result

:greatestNumber});
});

The numberWorkerDemo.html file contains the code for instantiating the number web worker and listening to response message. The following code shows the content of
numberWorkerDemo.html file.

<!DOCTYPE html>
<html>
<head lang="en">

< meta charset="UTF-8">
<title>Time Web Worker Demo</title>
</head>
<body>
<h1 id="resultContainer"></h1>
<input type="number" id="number1" value="7" placeholder="Enter first number"> <input type="number" id="number2" value="9" placeholder="Enter second number">
<button id="greatButton">Find Greatest Number</button>
<script>
var numberWorker = new Worker("numberWorker.js"),
resultContainer = document.getElementById("resultContainer"), greatButton = document.getElementById("greatButton"),
number1 = document.getElementById("number1"),
number2=document.getElementById("number2");
greatButton.addEventListener("click",function(){
numberWorker.postMessage({
number1:parseInt(number1.value,10),
number2: parseInt(number2.value,10)
});
});
numberWorker.addEventListener("message",function(workerEvent){ var responseData = workerEvent.data;
resultContainer.innerText = "Greatest Number: "+responseData.result;
});
</script>
</body>
</html>

The output of this code is rendered as following screenshot containing the greatest number from the supplied numbers.

Q. Create a shared worker to calculate the length of a string? ANSWER
The calculateLengthWorker.js contains the code for listening messages and calculates the length of input string. The shared worker listens to message in a port by listening to connect event. The code for calculateLengthWorker.js file is as follows.

self .addEventListener("connect", function (event) {
var port = event.ports[0];
port.addEventListener("message", function (event) {

var requestData = event.data,
inputString = requestData.string,
stringLength = inputString.length;

port .postMessage({result:stringLength});
}, false);
port.start();

}, false

);

The lengthWorkerDemo.html file contains the code for instantiating the shared worker and rendering the response in browser. The code content of lengthWorkerDemo.html file are listed as follows.

<!DOCTYPE html>
<html>
<head lang="en">

< meta charset="UTF-8">
<title>Shared Web Worker Demo</title> </head>
<body>

< h1 id="resultContainer"></h1>
<input type="text" id="inputString" value="Hello" placeholder="Enter a string"> <button id="lengthButton">Get Length</button>
<script>

var lengthWorker = new SharedWorker("calculateLengthWorker.js"), resultContainer = document.getElementById("resultContainer"), lengthButton = document.getElementById("lengthButton"), inputString = document.getElementById("inputString");

lengthButton .addEventListener("click", function () {
resultContainer.innerText = "";
lengthWorker.port.postMessage({

string :inputString.value
});
});
//start the worker
lengthWorker.port.start();
//Success Handler for the worker
lengthWorker.port.addEventListener("message", function (workerEvent) {

var responseData = workerEvent.data,
result = responseData.result;
resultContainer.innerText = "Result: " + result;
});
</script>
</body>
</html>

The output of the preceding code is rendered as following screenshot displaying length of the input string.