I am trying to write a web worker that performs an interruptible computation. The only way to do that (other than Worker.terminate()) that I know is to periodic
I can confirm the 4ms round trip time of setTimeout(..., 0), but not consistently. I used the following worker (start with let w = new Worker('url/to/this/code.js', stop with w.terminate()).
In the first two rounds the pause is sub 1ms, then I get one in the range of 8ms and then it stays around 4ms each further iteration.
To reduce the wait I moved the yieldPromise executor in front of the workload. This way setTimeout() can keep it’s minimum delay without pausing the work loop longer than necessary. I guess the workload has to be longer than 4ms to be effective. That should not be a problem, unless catching the cancel message is the workload... ;-)
Result: ~0.4ms delay only. I.e. reduction by at least factor 10.1
'use strict';
const timer = performance.now.bind(performance);
async function work() {
while (true) {
const yieldPromise = new Promise(resolve => setTimeout(resolve, 0));
const start = timer();
while (timer() - start < 500) {
// work here
}
const end = timer();
// const yieldPromise = new Promise(resolve => setTimeout(resolve, 0));
await yieldPromise;
console.log('Took this time to come back working:', timer() - end);
}
}
work();
1 Isn’t the browser limiting the timer resolution to that range? No way to measure further improvements then...