Web workers is a JavaScript technology for browsers to support running of the script independently in a separate thread from the main thread. It is like a background process without affecting the screen.
To apply this, you will need to create a worker file and create an instance of the worker file in the main script file. Let’s say ‘app-worker.js’ is the worker JS file and ‘main.js’ is a script file referred to in the HTML page(view page in our application). We can perform operations through the worker file by sending messages to the worker file using postMessage in the format (json, string..) such as
A sample of creating an instance and sending data is as follows
const workerScript = new Worker('app-worker.js'); // Create instance of worker file
workerScript.postMessage({ type:'setToken', value: 'token_value' }); // send whatever the type of information
The worker file will receive this data using the ‘onmessage’ listener as follows:
onmessage = function(event) {
console.log('Type of action to be performed:', event.value);
};
Once the operation is complete inside the worker script, a message can be sent back to the main thread(main.js)
self.postMessage({success: true, response: responseData});
And inside the main.js, you can listen to the message as follows –
workerScript.onmessage = function (event) {})
In the worker scripts, we can not use packages like jQuery because these are based on Dom Manipulation, although we can load jquery inside the worker file by creating a dummy, fake document object. It will not support AJAX methods from jQuery such as $.ajax, $.get, $.post, which rely on the XMLHttpRequest. Instead of this, you can use fetch() Api and Below is a sample of a writing worker script for api calls through a script file.
let appToken = null;
let baseUrl = null;
let permissions = null;
let settings= null;
onmessage = function (event) {
const { type, value } = event.data;
if (type === 'setToken') {
appToken = value;
}
else if (type === 'initApplication') {
url = value.url;
serviceSettings= value.settings;
…..
}
else if (type === 'dataServiceOperation') {
serviceCall(value);
}
function serviceCall(value) {
if (value.method) {
switch (value.method) {
case 'get':
getJsonAsync(value);
break;
case 'post':
postJsonAsync(value);
break;
case 'patch':
patchJsonAsync(value);
break;
case 'delete':
deleteAsync(value);
break;
}
}
}
async function getJsonAsync(value) {
// Response type is json in this get request
if (appToken !== "" && appToken != null) {
try {
let url = baseUrl + value.requestUrl;
let settings = {
method: "GET",
dataType: 'JSON',
headers: {
"Authorization": 'Bearer ' + appToken
},
};
const response = await fetch(url, settings);
const status = response.status;
const isSuccess = response.ok;
const statusText = response.statusText;
let responseData = null;
if (isSuccess) {
if (value.passResponse) {
try {
responseData = await response.json(); // Only if you expect JSON
} catch (e) {
responseData = null; // Or fallback to response.text() if needed
}
}
}
else {
responseData = await response.text();
}
if (isSuccess)
self.postMessage({ type: "apiResponse", success: isSuccess, data: responseData, value }); // Send back whatever data is required for further processing in the main
else
self.postMessage({ type: "apiResponse", success: isSuccess, errObject: { status, statusText, responseText: responseData }, error: "get failed."});
} catch (err) {
self.postMessage({ type: "apiResponse", success: false, error: err.message, });
}
}
else {
self.postMessage({ type: "apiResponse", success: false, error: “token invalid”});
}
}
async function postJsonAsync(value) {
try {
let url = dataServiceUrl + value.requestUrl;
let settings = {
method: "POST",
body: value.postJsonBody,
headers: {
'Authorization': 'Bearer ' + appToken,
'Content-Type': 'application/json'
},
};
const response = await fetch(url, settings);
const status = response.status;
const statusText = response.statusText;
const isSuccess = response.ok;
let responseData = null;
if (isSuccess) {
if (value.passResponse) {
try {
responseData = await response.json();
} catch (e) {
responseData = await response.text(); // Or fallback to response.text() if needed
}
}
}
else {
responseData = await response.text();
}
// const data = await response.json();
if (isSuccess)
self.postMessage({ type: "apiResponse", success: isSuccess, data: responseData});
else
self.postMessage({ type: "apiResponse", success: isSuccess, errObject: { status, statusText, responseText: responseData }, error: "post failed."});
} catch (err) {
self.postMessage({ type: "apiResponse", success: false, errObject: { status:0, statusText:"", responseText: err.message }, error: "catch error."});
}
}
// ……… similarly other calls
};