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"
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With