.runWorker() 方法来执行 worker。在
.runWorker() 方法中,我们必须把当前 worker 的
activeWorkersById 设置为使用状态;为
message 和
error 事件设置事件监听器(并在之后清理它们);最后将数据发送给 worker。
private async runWorker(workerId: number, queueItem: QueueItem<T, N>) {
const worker = this.workersById[workerId]; this.activeWorkersById[workerId] = true;
const messageCallback = (result: N) => {
queueItem.callback(null, result);
cleanUp();
};
const errorCallback = (error: any) => {
queueItem.callback(error);
cleanUp();
};
const cleanUp = () => {
worker.removeAllListeners('message');
worker.removeAllListeners('error');
this.activeWorkersById[workerId] = false;
if (!this.queue.length) {
return null;
}
this.runWorker(workerId, this.queue.shift());
};
worker.once('message', messageCallback);
worker.once('error', errorCallback);
worker.postMessage(await queueItem.getData());
}
首先,通过使用传递的
workerId,我们从
workersById 中获得 worker 引用。然后,在
activeWorkersById 中,将
[workerId] 属性设置为true,这样我们就能知道在 worker 在忙,不要运行其他任务。接下来,分别创建
messageCallback 和
errorCallback 用来在消息和错误事件上调用,然后注册所述函数来监听事件并将数据发送给 worker。在回调中,我们调用
queueItem 的回调,然后调用
cleanUp 函数。在
cleanUp 函数中,要删除事件侦听器,因为我们会多次重用同一个 worker。如果没有删除监听器的话就会发生内存泄漏,内存会被慢慢耗尽。在
activeWorkersById 状态中,我们将
[workerId] 属性设置为
false,并检查队列是否为空。如果不是,就从
queue 中删除第一个项目,并用另一个
queueItem 再次调用 worker。接着创建一个在收到









