0

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;
  }
}

1 Answer 1

2

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;
  }
}
Sign up to request clarification or add additional context in comments.

9 Comments

Thanks, it looks promising. I'll try it out tomorrow and then report back!
The approach is good, but notice that you cannot call calculation multiple times concurrently with this code.
@Bergi Yeah, I did that on purpose as it seemed that's the way the OP wanted it.
…but it leads to broken promises. If that's what you really want, I'd suggest adding a if (this.worker.onmessage != null) throw new Error("…") in the first line of the new Promise executor. That way the mistaken call will get a rejected promise, instead of letting the previous promise dangle by overwriting its listener.
@Bergi Ah, fair enough; I've updated my response to reflect. Thanks!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.