Description
What problem are you trying to solve?
Some of the codes require extremely high performance. Therefore, these codes will use Web Worker and make their codes like this:
state = "A_STATE"
while (true) {
switch (state) {
...
}
}
Therefore, this Web Worker will never release the CPU and give the browser a chance to execute the event loop, which means, dozens of API, including self.onmessage
, fetch
, OffscreenCanvas
cannot being used in this context.
What solutions exist today?
For the developers of these applications, they will use SharedArrayBuffer
to receive the messages from the main thread, as this API provide a way to transfer messages without releasing the CPU.
They even use the XHR request and set sync=true
to send a request to a ServiceWorker and transfer things back by catching this network request.
Some people may argue that why they don't refactor there codes to something like this:
let step = 0;
let executePart = () => { ... }
setTimeout(function myself() {
executePart()
setTimeout(myself)
}, 0)
These codes will reduce the performance as each executePart
will wait about 4 - 10 ms before getting execute.
How would you solve it?
Adding an API like processEventLoop()
for WebWorker only.
This API can be invoked in any place in WebWorker. Once it's invoked, the browser will pause this JS code and execute things including promise
, setTimeout
, event handle (onmessage
, ...).
The codes will be like:
let queue = []
self.onmessage = (ev) => { queue.push(...) }
while (true) {
for (let ev of queue) {
...
}
execute();
processEventLoop()
}
This API can also take one argument, which is a promise, like let result = processEventLoop(fetch( ... ))
.
This is like await, but it's not required to invoked in a async function.
(The problem that why we don't use async function is that this will also reduce performance)
Anything else?
These API are strange because they provide another way to execute a promise. It's like OffscreenCanvasContext2D.commit()
, as this provides a solution without release the CPU.