Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to pass a callback to a webworker?

I have a render worker that I would like to pass a callback to. I know that the worker.postMessage method now supports Javascript Objects, but when I try to pass a function withing the object I get an error telling me that it "couldn't clone" the object.

I also tried JSON.stringify() on the object, and learned that functions don't get stringified because JSON doesn't support function scope.

Is there a way to pass a callback to a Web Worker? If not, how would you suggest working around the limitation?

My issue is that I send the worker a message to start the rendering at the same time I start an animation. So I need to wait until BOTH are finished before executing the "callback"

like image 861
Native Coder Avatar asked May 23 '17 16:05

Native Coder


People also ask

How to send in functions from a web worker?

You see, when you have an instance of a Web Worker, you may send in data through postMessage worker.postMessage( { string: 'string', number: 0, array: [], ... }); Those value types above can be handled by the structured cloning. However, you cannot send in functions because they can be neither cloned nor transferred.

What are the limitations of web worker?

Additionally, there some limitations to their usage, such as the inability to pass functions into them. Web worker is a mere script that runs in the background, in another thread, which means that any calculation, however expensive, will not block the UI's thread. That's huge. People hate when websites become slow or even worse, non-responsive.

What is the use of web workers?

With Web Workers, you can do the heavy lifting in the background while showing the user a loading indicator and letting him or her do whatever else in the meantime. You may ask when this is useful.


1 Answers

Is there a way to pass a callback to a Web Worker?

From MDN:

The postMessage() method of the Worker interface sends a message to the worker's inner scope. This accepts a single parameter, which is the data to send to the worker. The data may be any value or JavaScript object handled by the structured clone algorithm, which includes cyclical references.

And also:

Things that don't work with structured clones

  • Error and Function objects cannot be duplicated by the structured clone algorithm; attempting to do so will throw a DATA_CLONE_ERR exception.

So No. You can't pass functions about.

My issue is that I send the worker a message to start the rendering at the same time I start an animation. So I need to wait until BOTH are finished before executing the "callback"

Generate a unique ID (e.g. a timestamp concatenated with a random number). Store it. Associate whatever data you like (including the function you want to use as a callback). Pass it to your end of animation handler and the web worker.

Send that ID back when the work is finished. Listen for events with that ID in them, and look it up in your data structure.

like image 58
Quentin Avatar answered Oct 31 '22 04:10

Quentin