Search code examples
javascriptasynchronousweb-worker

How to use asynchronous javascript code with web workers in a class


I wrote a javascript class, that upon instantiation creates a web worker. Another method in this class runs the worker. I want to invoke the method running the worker and then do something afterwards asynchronously. For a better understanding I added a schematic code skeleton below.

I tried to generate and store a Promise in a class variable and then act upon it, but it seemed to be a wrong ansatz. Link to the JS Bin.

class Task{
  constructor(){
    this.data = 0;
    //this.listen; //my idea, does not work
    this.worker = new Worker('worker.js');

    this.worker.onmessage = (function(e){
      // worker constantly emits messages
      let data = e.data.split(' ');
      // suppose message is now availabe as array
      this.data = data;

      if(data.includes("trigger")){
        //trigger signals that the heavy computation is over

        /* my idea didn't work:
        *this.listen = Promise.resolve(1);
        */
      }
    }).bind(this);
  }

  async doTask(){
    this.worker.postMessage("start computation");
    //wait for the worker to finish calculation
    /*my idea
    *await this.listen;
    */

    //do something after trigger was sent
    return 0;
  }
}

Solution

  • perhaps something like this?

    class Task{
      constructor(){
        this.data = 0;
        this.worker = new Worker('worker.js');
      }
      async calculation() {
        if (this.worker.onmessage === null) {
          return new Promise(resolve => {
            this.worker.onmessage = e => {
              let data = e.data.split(' ');
              // suppose message is now availabe as array
              this.data = data;
    
              if(data.includes("trigger")){
                this.worker.onmessage = null;
                resolve();
              }
            };
            this.worker.postMessage("start computation");
          });
        } else {
          console.log('One calc at a time please...');
        }
      }
      async doTask(){
        await this.calculation();
    
        //do something after trigger was sent
        return 0;
      }
    }