【发布时间】:2022-12-23 03:29:00
【问题描述】:
我在我的 React 应用程序中使用 web worker 和一个如下所示的帮助程序类:
export class WebWorker {
constructor(worker) {
const code = worker.toString();
const blob = new Blob(["(" + code + ")()"]);
return new Worker(URL.createObjectURL(blob));
}}
工人看起来像:
export default () => {
self.addEventListener('message', function (e) {
switch (e.data.event) {
case 'start':
// Start back ground task
break;
case 'stop':
// Stop background task
break;
}
}, false);
然后我可以使用创建工人
let sessionWorker = new WebWorker(SessionWorker);
sessionWorker.postMessage({event: "start"})
这工作正常,但是我现在需要使用 SharedWorker 并且我无法让它工作。我发现的所有资源都显示了常规网络工作者。有这个 SO Question Using Shared Worker in React 但它对我不起作用。它实际上看起来与我的常规 WebWorker 代码相同,但这不起作用,因为 SharedWorkers 要求您实现 onconnect 函数,而我不明白该怎么做。我发现的非反应示例将工作脚本显示为:
onconnect = function(e) {
var port = e.ports[0];
port.onmessage = function(e) {
var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
port.postMessage(workerResult);
}
}
但是如果我把它放在我的 worker js 文件中并使用 WebWorker 帮助程序遵循相同的模式,则 worker.toString() 只会返回 [object Window] 并且它永远不会被执行。我不明白如何创建将被调用的“onconnect”函数。我试过这样的变化:
import React from 'react';
self.onconnect = (e) => {
var port = e.ports[0];
console.log("test log");
port.onmessage = function(e) {
console.log("Message received ", e)
port.postMessage("test");
}
}
export default self;
最终没有什么对我有用。显然我根本不了解 Javascript 中的导出。如果我只是导出一个名为 onconnect 的函数,它永远不会被调用,显然 onconnect 必须属于某种类似类的上下文(如 Window 或 Self),但我不明白需要什么
谢谢, 特洛伊。
【问题讨论】:
-
实际上,我似乎最终确实让它工作了,但我不知道它在工作,因为共享工作者的控制台日志转到了不同的日志。您需要从 url“chrome://inspect/#workers”查看共享的 worker 日志(至少在 Chrome 中)。所以我的共享工作人员可以工作,但我还有另一个问题,即 URL.createObjectURL(blob) 每次都会创建一个新的 URL,因此共享工作人员实际上并未共享,而是在每个实例中重新启动。
-
我有这个工作,但我无法在我的共享工作人员中导入模块。如果我将 { type: 'module'} 添加到我的实例化中,它无法加载 worker,仅显示消息“无法获取 worker 脚本。”。如果我没有类型:'module',那么我会在 worker 中收到错误“Uncaught ReferenceError:cuid__WEBPACK_IMPORTED_MODULE_0___default is not defined”。
标签: javascript reactjs web-worker shared-worker