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;
}
如果你有兴趣,我也实现了









