Let's say I had a WebWorker file called ticker.js
that consisted of this:
function tick() {
postMessage(1);
}
setInterval(tick, 1);
And then in the main JavaScript program I had this:
let ready = true;
let prevTime = 0;
function sometimesLongTask() {
ready = false;
if (performance.now() - prevTime > 30) {
// a very long CPU intensive task, like a loop which takes a while to complete
prevTime = performance.now();
}
ready = true;
}
const intervalWorker = new Worker('ticker.js');
intervalWorker.onmessage = function() {
ready && sometimesLongTask();
};
Would this cause a memory leak?
I think it won't, but I'm not sure. My logic is that while sometimesLongTask
will sometimes take a while (when 30 milliseconds have passed), 99% of the time it will execute immediately. As such, even though a new tick
is added to Javascript's event queue every millisecond, every once in a while Javascript can speed through all of those and clear them out since the majority of them will not need to execute. Is this indeed the case?
Also, do I even need the ready flag here, or is it doing nothing (and I can get rid of it)? I think it might be doing nothing because Javascript is single-threaded, so even though the WebWorker might post multiple messages very quickly, Javascript cannot run multiple instances of sometimesLongTask
at the same time. Correct?
CodePudding user response:
Yes, this won't cause a memory leak, since that by definitions means memory allocations not being released despite no longer being needed. The events in the message queue are still needed though, they will eventually be received by the worker.
But you won't even get growing memory usage. This is solely due to the prevTime
comparison though - we can assume that all queued events can be handled (by doing nothing) in the 30ms between the runs of the long task.
Do I even need the
ready
flag here, or is it doing nothing?
It indeed does nothing useful. Notice it is always true
when the onmessage
handler is executed. The onmessage
handler will never interrupt your synchronous sometimesLongTask
during which it is set to false
.