Th0*_*gal 10 javascript web-worker reactjs webpack
我已经尝试将 Web Workers 与 React 一起使用几天了,但遇到了一些问题。
我从使用 webpack 4 的 create-react-app 开始。我可以使用本教程使用 Web Worker: https: //javascript.plainenglish.io/web-worker-in-react-9b2efafe309c,它以这种方式加载 WebWorker:
export default class WorkerBuilder extends Worker {
constructor(worker) {
const code = worker.toString();
const blob = new Blob([`(${code})()`]);
return new Worker(URL.createObjectURL(blob));
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我需要使用我的工作人员(d3-delaunay)中的一个库,当我尝试这样做时,webpack 给了我一个错误(我认为它改变了它的路径)。
我听说过worker-loader,并且了解到它已被弃用,因为Web Worker导入现在是在webpack 5中内置的。
我将我的应用程序更新到了 WebPack 5(如 create-react-app wiki 中所述),这并不容易,因为我的很多依赖项都损坏了。
但是当我尝试加载我的 WebWorker 时,如下所述: https: //webpack.js.org/guides/web-workers/ 这根本不起作用(没有错误)。
这是我的代码:
console.log("hello");
const worker = new Worker(new URL('./world.worker.js', import.meta.url));
worker.postMessage({
question:
'The Answer to the Ultimate Question of Life, The Universe, and Everything.',
});
worker.onmessage = ({ data: { answer } }) => {
console.log(answer);
};
console.log("world");
Run Code Online (Sandbox Code Playgroud)
还有我的 world.worker.js:
import { Delaunay } from "d3-delaunay";
// eslint-disable-next-line import/no-anonymous-default-export
export default () => {
// eslint-disable-next-line no-restricted-globals
self.onmessage = (message) => {
console.log("yolo");
};
};
Run Code Online (Sandbox Code Playgroud)
但我唯一的输出是:
hello
world
Run Code Online (Sandbox Code Playgroud)
我的工人似乎没有工作。
小智 10
我终于弄清楚了,我也遇到了同样的问题。最大的问题是您不应该在 Web Worker 中使用导出默认值。这是我让它发挥作用的方法。
您需要使用 React.useMemo 实例化工作线程。这样就只创建了一名工人。
const worker = React.useMemo(() => new Worker(new URL('./world.worker.js', import.meta.url)), []);
Run Code Online (Sandbox Code Playgroud)
要获得响应,您需要知道工作对象何时更新。为此,您可以使用 React.useEffect。
React.useEffect(() => {
worker.onmessage = ({ data: { answer } }) => {
console.log(answer);
return () => worker.terminate();
}
}, [worker]);
Run Code Online (Sandbox Code Playgroud)
最后,您的 world.worker.js 文件有两个问题。第一个是它实际上不返回任何内容。您需要添加对 postMessage 的调用。我很难解决的第二个问题是,您不应该将函数包装在导出默认值中。我认为这是因为 webpack 会为你包装它。请参阅下面的正确 world.worker.js 代码。
import { Delaunay } from "d3-delaunay";
self.onmessage = ({ data: { question } }) => {
postMessage({
answer: 42,
});
};
Run Code Online (Sandbox Code Playgroud)
小智 -1
要在worker中使用es6模块,您需要使用以下语法以脚本模式加载它:
new Worker('worker-path.js', {type: 'module'})
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6025 次 |
最近记录: |