Node.js 多线程完全指南总结

2020-06-17 06:09:52易采站长站整理
实例,用于与父线程通信。

threadId

分配给 worker 的唯一标识符。

现在我们知道了技术细节,接下来实现一些东西并在实践中检验学到的知识。

实现

setTimeout

setTimeout
是一个无限循环,顾名思义,用来检测程序运行时间是否超时。它在循环中检查起始时间与给定毫秒数之和是否小于实际日期。


import { parentPort, workerData } from 'worker_threads';

const time = Date.now();

while (true) {
if (time + workerData.time <= Date.now()) {
parentPort.postMessage({});
break;
}
}

这个特定的实现产生一个线程,然后执行它的代码,最后在完成后退出。

接下来实现使用这个 worker 的代码。首先创建一个状态,用它来跟踪生成的 worker:


const timeoutState: { [key: string]: Worker } = {};

然后时负责创建 worker 并将其保存到状态的函数:


export function setTimeout(callback: (err: any) => any, time: number) {
const id = uuidv4();

const worker = runWorker(
path.join(__dirname, './timeout-worker.js'),
(err) => {
if (!timeoutState[id]) {
return null;
}

timeoutState[id] = null;

if (err) {
return callback(err);
}

callback(null);
},
{
time,
},
);

timeoutState[id] = worker;

return id;
}

首先,我们使用 UUID 包为 worker 创建一个唯一的标识符,然后用先前定义的函数

runWorker
来获取 worker。我们还向 worker 传入一个回调函数,一旦 worker 发送了数据就会被触发。最后,把 worker 保存在状态中并返回
id

在回调函数中,我们必须检查该 worker 是否仍然存在于该状态中,因为有可能会

cancelTimeout()
,这将会把它删除。如果确实存在,就把它从状态中删除,并调用传给
setTimeout
函数的
callback

cancelTimeout
函数使用
.terminate()
方法强制 worker 退出,并从该状态中删除该这个worker:


export function cancelTimeout(id: string) {
if (timeoutState[id]) {
timeoutState[id].terminate();

timeoutState[id] = undefined;

return true;
}

return false;
}

如果你有兴趣,我也实现了