我正在学习使用VSCode的javascript中的Web Workers。我的worker在其onmessage事件期间设置了一个时间间隔。理想情况下,调用start只会在尚未运行的情况下创建时间间隔。
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;
}
}问题是interval是在函数的执行过程中定义的,所以我可以启动多个时间间隔,而不需要让它们中的任何一个知道彼此。
const worker = new Worker("myworker.ts");
worker.postmessage({command: "start"});
worker.postmessage({command: "start"});
worker.postmessage({command: "start"});如果我将web worker代码修改为使用全局变量,则根据VSCode,其他worker文件将可以访问间隔变量:
let interval; // Error: `interval` is already defined in `anotherWorker.ts`
onmessage = () => {
// ...
if (!interval){
interval = setInterval(myFunction, 1000);
}
// ...
if (interval){
clearInterval(interval);
interval = null;
}
}即使每个worker都有自己的作用域,如果我在worker之间重用变量名,VSCode也会继续抛出错误。
如何为worker onmessage函数创建本地状态?
发布于 2020-07-08 15:38:17
您可以将onmessage处理程序包装在它自己的块中,并在那里声明您的interval。这样,其他模块将看不到它,但它仍然会在不同的消息事件中持续存在。
{ // <- 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;
}
};
}发布于 2021-09-28 17:02:38
我最近遇到了一些问题,比如@Kaiido在一个服务工作者中的回答。浏览器可能会重新启动服务工作进程(以及可能的其他工作进程?)只要它们认为合适,那么您就可以丢失存储在worker中的变量中的状态。
在我的示例中,我创建了一个服务工作者,以便在用户处于非活动状态时将应用程序的所有实例返回到登录页面。这有时会因为worker被浏览器重新启动并丢失我设置的超时而失败。
如果希望在服务工作进程重新启动时保持该状态,则应将该状态存储在IndexedDB中,并在任何工作进程本地化状态为reactivated时重新初始化该状态。
对于超时和间隔等需要工作人员保持活动状态的情况,您可以在合理的情况下强烈考虑将该功能转移到客户端应用程序中。否则,您可以考虑以您可以容忍的最大粒度定期发送keep-alive消息,以确保它将在该时间间隔重新激活,并有机会对本应在其休眠时触发的超时(通过存储在IndexedDB中的时间戳)采取行动。
https://stackoverflow.com/questions/62782282
复制相似问题