
本文介绍如何利用 Node.js 的 worker_threads 模块,将一个耗时的 Node.js 类自动转换为在独立的 worker 线程中运行,而无需手动编写大量的 worker 代码。通过封装一个 WrapWorker 函数,可以方便地将类及其方法暴露给主线程,实现异步执行,从而避免阻塞主线程,提高应用程序的响应能力。文章提供了详细的代码示例,并解释了其工作原理,帮助开发者快速上手。
Node.js 的 worker_threads 模块允许你在独立的线程中执行 JavaScript 代码,这对于执行 CPU 密集型任务非常有用,可以避免阻塞主线程,提高应用程序的响应速度。手动创建和管理 worker 线程可能比较繁琐,特别是当需要暴露类的多个方法时。本文介绍一种自动将 Node.js 类转换为 worker 的方法,通过封装 WrapWorker 函数,简化了 worker 的创建和管理过程。
WrapWorker 函数接收一个类 OBJECT 和一个包含构造函数参数的数组 OBJECT_ARGS 作为输入。它在主线程中创建一个新的 worker 线程,并将类的实例在 worker 线程中实例化。然后,它通过消息传递机制,将对类方法的调用转发到 worker 线程,并将结果返回给主线程。
以下是 WrapWorker 函数的实现:
const { Worker } = require('worker_threads');
function WrapWorker(OBJECT, OBJECT_ARGS) {
if (require('worker_threads').isMainThread) {
const workerCode = `
const { parentPort, workerData } = require('worker_threads');
const OBJECT = ${OBJECT.toString()};
const instance = new OBJECT(...workerData);
parentPort.on('message', async (data) => {
try {
const method = instance[data.method];
if (typeof method === 'function') {
const response = await method.apply(instance, data.arguments);
parentPort.postMessage({ rid: data.rid, valid: true, response });
} else {
parentPort.postMessage({ rid: data.rid, valid: false });
}
} catch (error) {
parentPort.postMessage({ rid: data.rid, valid: false });
}
});
`;
const instance = new Worker(workerCode, { eval: true, workerData: OBJECT_ARGS });
const methodsProxy = {};
const methods = Object.getOwnPropertyNames(OBJECT.prototype);
let rid = 0;
const requests = {};
for (const methodId of methods) {
methodsProxy[methodId] = (...args) =>
new Promise((resolve, reject) => {
rid++;
requests[rid] = { resolve, reject };
instance.postMessage({ method: methodId, arguments: args, rid });
});
}
instance.on('message', (data) => {
const request = requests[data.rid];
if (request) {
if (data.valid) {
request.resolve(data.response);
} else {
request.reject();
}
delete requests[data.rid];
}
});
return methodsProxy;
}
}
module.exports = WrapWorker;代码解释:
以下是如何使用 WrapWorker 函数的示例:
class RunInWorker {
constructor (starta, startb) {
this.sum = starta + startb;
}
addSync(a, b) {
return a + b + this.sum;
}
async addAsync(a, b) {
await (new Promise((resolve) => { setTimeout(resolve, 3000); }));
return a + b + this.sum;
}
}
/** @type {\RunInWorker} */
let worker = new require('./wrap-worker.js')(RunInWorker, [5, 5]);
(async () => {
console.log(worker);
console.log(await worker.addSync(3, 4), 'should be', 17);
console.log(await worker.addAsync(3, 8), 'should be', 21);
})();代码解释:
通过使用 WrapWorker 函数,可以方便地将 Node.js 类转换为 worker,从而避免阻塞主线程,提高应用程序的响应速度。这种方法简化了 worker 的创建和管理过程,并提供了一种简单的方式来暴露类的多个方法。 然而,也需要注意数据序列化和错误处理等问题,以便更好地利用 worker_threads 模块的优势。
以上就是自动将 Node.js 类转换为 Worker的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号