Web Worker: a way to run scripts in the background in different thread than the current main(Window)thread.
- Web workers vs asynchronous using event_loop
- Introduction to Web Workers
- how to create a web worker
- For example with a web worker
- limitation of Web Workers
- asynchronous operation in Web Workers
1. Web Workers vs Asynchronous Operations Using Event Loop
JavaScript typically handles asynchronous operations by placing tasks into corresponding queues (macro-task queue, micro-task queue), with the event loop continuously checking these queues and pushing tasks into the call stack when they're ready to be executed. This approach ensures non-blocking execution but still runs everything on a single thread.
Web Workers, on the other hand, allow scripts to run in a completely separate thread with its own call stack, asynchronous queues, and event loop. This separation prevents the main thread from being blocked by heavy computations or long-running tasks, as the worker operates independently.
2. Introduction to Web Workers
Web workers execute scripts in a different context than the main window context, enabling parallelism in web applications. The Web Worker API provides several types of workers:
- Dedicated Workers: Utilized by a single script, these are ideal for offloading tasks from the main thread.
- Shared Workers: Accessible by multiple scripts running in different contexts (e.g., different windows or iframes).
- Service Workers: Operate as a proxy server between web applications, the browser, and the network, providing functionalities like offline support and caching.
This article focuses on dedicated workers, which are the most straightforward to implement and commonly used.
3. How to Create a Web Worker
To create a web worker, you can use the following key methods:
-
new Worker()
: The constructor to create a new worker. -
postMessage()
: Sends messages from the main thread to the worker or vice versa. -
onmessage
: A callback function set to handle messages received by the worker. -
terminate()
: Stops the worker immediately.
4. Simple Example
Let’s create a worker to fetch data from an API, specifically dog images from the Dog CEO API.
4.1 Worker Code
Here’s the implementation of the worker script. Notice that inside the worker, self
is used to refer to the global context:
if (window.Worker) {
const worker = new Worker("/src/worker.js");
worker.postMessage({
operation: "get_dog_imgs",
url: "https://dog.ceo/api/breeds/image/random",
count: 5 //number of photos
});
worker.onmessage = (e) => {
console.log(e.data);
if (e && e.data) {
setdata((old) => [...old, e.data]); // update react state
showCallStack(); // function to show the callstack
}
};
worker.onerror = (e) => {
console.log(e);
};
}
In this code, the worker listens for messages (onmessage
) and fetches data from the given URL multiple times as specified by the count.
Here’s what the call stack looks like inside the worker:
4.2 Client Code
The main thread uses the worker like this:
self.onmessage = (event) => {
const data = event.data;
if (data && data.url && data.count) {
fetchFromUrls(data.url, data.count);
}
}
// fetch single data
const fetchdata = async (url) => {
const res = await self.fetch(url);
return await res.json();
};
const fetchFromUrls = async (url, count) => {
showCallStack(); // showing the callstack of the worker
for (const i of new Array(count).fill(0)) {
let data = await fetchdata(url);
if (data && data.message) {
self.postMessage({ type: "img", data: data.message });
}
}
};
This code demonstrates how to send a message to the worker and receive the fetched data in the main thread.
for full code go to code
5. Limitations of Web Workers
While web workers run in a separate thread from the main window thread, they come with certain limitations:
- No Access to DOM: Workers cannot directly manipulate the DOM. Communication with the main thread is necessary to update the UI.
- Resource Consumption: Overusing web workers can lead to high memory usage, as each worker requires additional resources to operate independently.
Top comments (0)