This is an issue that I also ran into while working with Pyodide. I wanted to 'synchronously' call a function from the main thread.
One solution involves the Atomic
s and SharedArrayBuffer
APIs. From the perspective of the web worker, this looks like the following
postMessage
the main thread
- freeze ourselves with
Atomics.wait
- get unfrozen by the main thread
- read the result from a
SharedArrayBuffer
. We can't receive the result as a postMessage
, because there isn't a synchronous way of asking "did I get a message".
Of course this requires a fair amount of extra code to handle all the serialization, data passing and more.
The main limitation is that to use those APIs, one needs to have the COOP/COEP headers set. The other bit to keep in mind is that this only works on recent browsers such as Safari 15.2 (released in December 2021).
There is also an alternative solution with synchronous XHR and a service worker, but I haven't investigated that option.