我正在尝试将一些密集的数据处理工作转移到React应用程序中的WebWorker。如果我在onmessage处理程序中使用promise或async / await调用任何异步函数,则会得到:
ReferenceError:_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___未定义默认值
这里是我的工人:
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有关。也许我在做其他错误。任何帮助是极大的赞赏。谢谢。
我通过一些更改解决了这个问题:
首先,我使用内联类型import合并了worker-loader库,例如:
import DataSyncWorker from 'worker-loader!./workers/DataSyncWorker';
然后,我不得不从原始实现的containing方法中解开内部函数,所以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`);
};
其他代码保持不变,现在一切正常。
我相信您可以使用另一种方法,包括修改modules.rules部分中的这些webpack.config.js:
{
test: /\.worker\.js$/,
use: ['worker-loader', 'babel-loader'],
include: [path.join(__dirname, 'src/workers')]
},
然后更新您的工作程序文件的名称,以便它与测试条件匹配,并更新它的导入等,但是我还没有尝试过,内联方法似乎更简单。