I'm learning Web Workers in javascript, using VSCode. My worker sets up an interval during its onmessage
event. Ideally calling start will only ever create the interval if it isn't already running.
onmessage = (event: MessageEvent) => {
let interval;
switch (event.data.command){
case "start":
if (!interval){
interval = setInterval(myFunction, 1000);
}
break;
case "stop":
if (interval){
clearInterval(interval);
interval = null;
}
break;
}
}
The problem is that interval
becomes defined within the execution of the function, so I could start multiple intervals without any of them knowing about one another.
const worker = new Worker("myworker.ts");
worker.postmessage({command: "start"});
worker.postmessage({command: "start"});
worker.postmessage({command: "start"});
If I modify the web worker code to use a global variable, like this, then according to VSCode other worker files will have access to the interval variable:
let interval; // Error: `interval` is already defined in `anotherWorker.ts`
onmessage = () => {
// ...
if (!interval){
interval = setInterval(myFunction, 1000);
}
// ...
if (interval){
clearInterval(interval);
interval = null;
}
}
Even if each worker gets its own scope, VSCode will continue to throw errors if I reuse variable names across workers.
How can I create a local state for the worker onmessage
function?
You can wrap your onmessage
handler in its own block, and declare your interval
there. This way, other modules won't see it, but it will still persist across different message events.
{ // <- defines a new block
let interval; // <- only for us, but still the same for all message events
onmessage = () => {
// ...
if (!interval){
interval = setInterval(myFunction, 1000);
}
// ...
if (interval){
clearInterval(interval);
interval = null;
}
};
}