WebWorker 内部的承诺(反应)抛出 babel/webpack 错误
Promises inside WebWorker (react) throwing babel/webpack error
我正在尝试将一些密集的数据处理卸载到 React 应用程序中的 WebWorker。如果我在 onmessage 处理程序中调用任何异步函数,使用 promises 或 async/await,我得到:
ReferenceError:
_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default is not defined
这是我的工人:
const DataSyncWorker = () => {
self.doSyncing = async () => {
return null;
};
self.onmessage = e => {
if (!e) return;
console.log(`worker received message in listener callback: ${e.data}`);
self.doSyncing();
self.postMessage(`SYNC_COMPLETE`);
};
};
export default DataSyncWorker;
以及创建Worker的设置文件:
export default class WebWorker {
constructor(worker) {
const code = worker.toString();
const blob = new Blob([`(${code})()`]);
return new Worker(URL.createObjectURL(blob));
}
}
并调用它:
import DataSyncWorker from './workers/DataSyncWorker';
import WebWorker from './workers/workerSetup';
const App = () => {
const dataSyncWorker = new WebWorker(DataSyncWorker);
dataSyncWorker.postMessage(`START_SYNC`);
dataSyncWorker.addEventListener(`message`, event => {
console.log(`index: message from worker: ${e.data}`);
});
}
如果我将 doSyncing 更改为非异步,一切正常。这是一个简化的示例,我已经确认它仍然表现出相同的行为。但是我无法使用 axios 或任何其他异步函数。据我了解,这应该是可能的,并且鉴于错误,我想知道我的问题是否与 babel/webpack 有关。或者也许我做错了什么。任何帮助是极大的赞赏。谢谢。
我通过一些改动解决了这个问题:
首先,我合并了 worker-loader 库,使用内联类型导入,如:
import DataSyncWorker from 'worker-loader!./workers/DataSyncWorker';
然后,我不得不从原始实现的包含方法中解包内部函数,所以 DataSyncWorker 现在看起来像这样:
doSyncing = async () => {
return null;
};
self.onmessage = e => {
if (!e) return;
console.log(`worker received message in listener callback: ${e.data}`);
doSyncing();
self.postMessage(`SYNC_COMPLETE`);
};
其他代码不变,现在一切正常。
我相信您可以使用另一种方法,包括修改 webpack.config.js,并在 modules.rules 部分添加以下内容:
{
test: /\.worker\.js$/,
use: ['worker-loader', 'babel-loader'],
include: [path.join(__dirname, 'src/workers')]
},
然后更新工作文件的名称,使其与测试条件匹配,并更新它的导入等,但我还没有尝试过,内联方法似乎更简单。
我正在尝试将一些密集的数据处理卸载到 React 应用程序中的 WebWorker。如果我在 onmessage 处理程序中调用任何异步函数,使用 promises 或 async/await,我得到:
ReferenceError: _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default is not defined
这是我的工人:
const DataSyncWorker = () => {
self.doSyncing = async () => {
return null;
};
self.onmessage = e => {
if (!e) return;
console.log(`worker received message in listener callback: ${e.data}`);
self.doSyncing();
self.postMessage(`SYNC_COMPLETE`);
};
};
export default DataSyncWorker;
以及创建Worker的设置文件:
export default class WebWorker {
constructor(worker) {
const code = worker.toString();
const blob = new Blob([`(${code})()`]);
return new Worker(URL.createObjectURL(blob));
}
}
并调用它:
import DataSyncWorker from './workers/DataSyncWorker';
import WebWorker from './workers/workerSetup';
const App = () => {
const dataSyncWorker = new WebWorker(DataSyncWorker);
dataSyncWorker.postMessage(`START_SYNC`);
dataSyncWorker.addEventListener(`message`, event => {
console.log(`index: message from worker: ${e.data}`);
});
}
如果我将 doSyncing 更改为非异步,一切正常。这是一个简化的示例,我已经确认它仍然表现出相同的行为。但是我无法使用 axios 或任何其他异步函数。据我了解,这应该是可能的,并且鉴于错误,我想知道我的问题是否与 babel/webpack 有关。或者也许我做错了什么。任何帮助是极大的赞赏。谢谢。
我通过一些改动解决了这个问题:
首先,我合并了 worker-loader 库,使用内联类型导入,如:
import DataSyncWorker from 'worker-loader!./workers/DataSyncWorker';
然后,我不得不从原始实现的包含方法中解包内部函数,所以 DataSyncWorker 现在看起来像这样:
doSyncing = async () => {
return null;
};
self.onmessage = e => {
if (!e) return;
console.log(`worker received message in listener callback: ${e.data}`);
doSyncing();
self.postMessage(`SYNC_COMPLETE`);
};
其他代码不变,现在一切正常。
我相信您可以使用另一种方法,包括修改 webpack.config.js,并在 modules.rules 部分添加以下内容:
{
test: /\.worker\.js$/,
use: ['worker-loader', 'babel-loader'],
include: [path.join(__dirname, 'src/workers')]
},
然后更新工作文件的名称,使其与测试条件匹配,并更新它的导入等,但我还没有尝试过,内联方法似乎更简单。