Is it possible for web workers to handle various events such as messages and progress updates simultaneously?

Can a web worker handle multiple events in response?

I've created a worker that loads buffergeometry from various .json files and passes it to the main thread upon receiving a 'message' event. The geometries load successfully, but I'm struggling to pass the progress of the xhr request back to the main thread. When I try to include a progress property, only 100% is transferred.

Is there a way to create a 'progress' event listener in the worker and send the progress as it happens to the main thread?

Although I am able to send buffer arrays and render Meshes in the Scene correctly, I cannot seem to get the progress of the data streaming over as desired.

I need help figuring out how to send the xhr req's progress from the worker to the main thread.

https://i.sstatic.net/zdlFd.jpg

Excerpt from Web Worker:

import { BufferGeometryLoader, BufferGeometry } from 'three';

var progress;

const loader = new BufferGeometryLoader();
const geometry = new BufferGeometry();

  /* Is this achievable? How do I stream progress info over here? */
  self.addEventListener('progress', (event) => {
    console.log('event in progress: ', progress);
  });

  self.addEventListener('message', (event) => {
    const { model, part } = event.data;
     loader.load(`https://models/${model}/${part}.json`, (geometry) => {
      // Code for loading buffergeometry and passing to main thread is removed for clarity
      },
      (xhr) => {
       /* How can I pass just the value of progress so I can display a progress bar in the DOM? Or emit a progress event that the worker can respond to? */
       progress = (xhr.loaded / xhr.total * 100);
       console.log('progress: ', progress);
      },
      (err) => {
        console.log('err: ', err);
      }
    );
  });

Main Thread Excerpt:

    /* If I can capture the progress data, I can easily build a loading progress bar */
    worker.addEventListener('progress', (event) => {
      console.log('event.data: ', event.data);
    });

    worker.addEventListener('message', (event) => {

      // Build meshes from buffergeometries, assign materials, and add to scene
    });

Answer №1

To achieve this functionality, utilize the message event and pass an object with a property (such as type) to differentiate the type of message being sent.

In your worker script, when updating the main thread with progress:

postMessage({type: "progress", progress: xhr.loaded / xhr.total * 100});

When sending data:

postMessage({type: "data", data: /*...*/});

In the main script, create an event handler for the message event that dispatches based on the value of type:

worker.addEventListener('message', (event) => {
    const msg = event.data;
    switch (msg.type) {
        case "progress":
            // ...handle progress message, access progress via `msg.progress`
            break;
        case "data":
            // ...handle data message, access data via `msg.data`
            break;
    }
});

Check out this live example on plnkr

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to display a jade template and insert it into a div using jquery?

I am attempting to load a jade page using the jQuery .load function. The goal is to load another jade template into a div on the index page when an anchor is clicked. The jQuery code for this action is provided below: $(document).ready(function(){ $( ...

Managing UIWebView using a web page

Is there a way to manipulate the UIWebView in an iOS application directly from a web page? Instead of adjusting the UIWebView's frame through Objective C, I am looking for a solution using Javascript code, similar to window.resizeTo() I have been to ...

Is there a way to generate a custom component on-the-fly using a string value

Hey there, I could really use some assistance with my process for creating a custom list of components. The method I'm using follows the same logic for 4 different components: Package, Theme, Part, and Knowledge. The only thing that changes is the com ...

Is TypeScript checking in VSCode failing to detect await functions?

I have been working on an app that retrieves weather data based on a user's location, and everything seems to be functioning correctly. However, during the coding process, I keep encountering errors that are being flagged, even though the code runs sm ...

Modify the name of the selected option value

I am working on an html code where I need to replace the values 0, 1, and 2 with USA, Australia, and Canada respectively. I also need to know the name of these values in my MySQL database. Thanks! HTML <form method="post" id="countriesForm" name="cou ...

jQuery tabs with carousel navigation

I am looking to enhance my jQuery tabs with a prev/next navigation in the form of a carousel. However, I am unsure of how to go about implementing this feature. Here is a snippet of my current code: Javascript <script type="text/javascript> ...

Exploring the capabilities of ngWebDriver to interact with a dynamic ng-repeat through Selenium

I'm currently in the process of automating a web interface that contains frames built with Angular JS. I'm specifically looking to access an ng-repeat located within dynamic columns. Here's a snippet of the DOM structure I'm dealing wi ...

Unable to use addEventListener on media queries exceeding 768px

When testing the site on Firefox 49 and Chrome 63, I encountered the same issue. Clicking on each card worked fine on iPhone4, Galaxy 5, and iPhone 8 using Chrome. However, after switching orientations from 640px to 320px portrait view, the top card would ...

Troubleshooting: Issue with Dependency Injection functionality in Angular 2 starter project

I’ve encountered a strange error whenever I attempt to inject any dependency TypeError: Cannot set property 'stack' of undefined at NoProviderError.set [as stack] (errors.js:64) at assignAll (zone.js:704) at NoProviderError.ZoneAwareError (zon ...

"Error: Unable to calculate the sum because s.sum is not recognized as a valid function. This occurred while trying to sum the property values of

I have a JavaScript object with JSON data var info = [ { "MONTH":" 2018-01", "DEPARTMENT":"Legals", "EMPLOYEE":"Smith A.", "AMOUNT":"14289.66" }, { "MONTH":" 2018-01", "DEPARTMENT":"Legals", "EMPL ...

Material UI - Radio buttons do not properly reflect the current state of the value

I'm diving into the world of full stack development and I'm working on a project to enhance my understanding of frontend programming with React JS and Material UI. Specifically, I've created a Dialog component to send data to the backend, bu ...

I am having trouble adding a second image. The functionality only seems to work for the first image input

How come I can't access the second file chooser when the first one works perfectly fine? This section contains HTML code <form action="<?php url("image/uploadImg"); ?>" method="post" en ...

Using PHP to have multiple buttons with unique names to dynamically update MySQL database through AJAX calls

I am facing a challenge where I have multiple buttons generated using a while loop, each with different names (button[$nostation]). Now, I need to update the MySQL database (table: smt, column: no) with the corresponding id ($nostation). Can someone guid ...

How do I deactivate dragControls in THREE.JS after enabling them for a group of elements?

My function currently activates dragControls when the "m" key is pressed, but for some reason, it doesn't deactivate when the key is released. How can I go about disabling the dragControls? I attempted to encapsulate the dragControls activation based ...

How can I set the textbox focus to the end of the text after a postback?

In my ASP.Net form, there is a text box and a button. When the user clicks the button, it adds text to an ASP:TextBox during a postback (it adds a specific "starter text"). After the postback, I want the focus to be set to the end of the text in the textbo ...

What is the best way to configure input fields as readonly, except for the one being actively filled by the user

Is there a way to make all input fields readonly except the one that the user is trying to fill data into? After the user loads the page index.php and attempts to input data into, for example, <input id="edValue2" ...>, I want to set all input field ...

Navigating to a different page in the app following a document update: a step-by-step guide

I am facing an issue with a page where I am trying to print a specific DIV using the script below... function printReceiptDiv() { var divElements; if (vm.isDLR) { divElements = document.getElementById("DLRreportCont ...

Activate search bar by clicking on it

I am currently attempting a basic jQuery example to expand a search bar on mouse click, but for some reason, my code is not working as expected. I have a simple jQuery function to display the input field when the button with the class "expand" is clicked, ...

What is the best way to generate a fresh object using an existing object in Javascript?

Struggling with generating a new object from the response obtained from an ajax call in JavaScript app. The data received is an array of objects, shown below: { "items": [ { "id": "02egnc0eo7qk53e9nh7igq6d48", "summary": "Learn to swim ...

Validating properties of a class using Typescript's Class-Validator

I tried using the class-validator decorator library for validation processes on my sample project. However, it doesn't seem to be working as expected. The sample project aims to create projects based on user inputs, and I'm attempting to validate ...