简体   繁体   中英

JavaScript: Is it possible to use generator functions in web workers?

I would like to stream some data from a web worker to the parent process. I tried to do so using:

var s = `
  self.onmessage = function(event) {
    postMessage(self.process(event.data))
  };
  self.process = function* (n) {
    for (var i=0; i<n; i++) yield i;
  }
`
var blob = new Blob([s], {type: 'application/javascript'});
var worker = new Worker(URL.createObjectURL(blob));

worker.onmessage = e => {console.log('got back', e.data)}
worker.postMessage(7);

But this throws Uncaught DOMException: Failed to execute 'postMessage' on 'DedicatedWorkerGlobalScope': [object Generator] could not be cloned. . Replacing "yield" with "return" and removing the star from the function declaration makes the error go away (but it prevents one from streaming results to the parent process of course).

Does anyone know how one can use generators in web workers? Any pointers others can offer on this question would be greatly appreciated!

Calling the generator with sef.process() returns an iterator, that has a next function. That next function cannot be sent back to the main agent and called there, that would break the seperation of agents, so this cannot be done at all. You have to consume the iterator in the worker and only send the results with messages.

  // In the worker: Consume the iterator:

  self.onmessage = function(event) {
     const it = self.process(event.data); // this contains a function, so it has to stay here
     let result;
     do { 
        postMessage(result = it.next());  // but the iteration objects can be sent, they onyl contain a number and a boolean
      } while(!result.done);         
  };

  self.process = function* (n) {
    for (var i=0; i<n; i++) yield i;
  };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM