有没有办法将 node.js 类转换为 worker,以便它可以在单独的线程中执行?

编程入门 行业动态 更新时间:2024-10-03 08:22:09

有没有办法将 node.js 类转换为 worker,以便<a href=https://www.elefans.com/category/jswz/34/1648819.html style=它可以在单独的线程中执行?"/>

有没有办法将 node.js 类转换为 worker,以便它可以在单独的线程中执行?

我有一个耗时的任务要在 node.js 服务器上执行。我想测试它在单独的线程中运行时的性能。我想从工人那里公开课程,而不必手动编写每个部分的代码。是否有可以执行此操作的节点内部功能或模块?谢谢

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);
})();

我目前正在将课程转换为字符串,而不是即时创建一个工人,但我认为这不是最好的方法......

// wrap-worker.js
const { Worker, isMainThread } = require('worker_threads');

function WrapWorker(OBJECT, OBJECT_ARGS) {

  if (isMainThread) {

    let workerCode = `
const { parentPort, workerData } = require('worker_threads');

let OBJECT = ` + OBJECT.toString() + `

let INSTANCE = new OBJECT(...workerData);

parentPort.on('message', async function (data) {
  if (data.method) {
    let method = INSTANCE[data.method];
    if (typeof method === 'function') {
      let response;
      if (method.constructor.name === 'AsyncFunction') response = await method.apply(INSTANCE, data.arguments);
      else response = method.apply(INSTANCE, data.arguments);
      parentPort.postMessage({ rid: data.rid, valid: 1, response: response });
    } else {
      parentPort.postMessage({ rid: data.rid, valid: 0 });
    }
  }
});`;

    let instance = new Worker(workerCode, { eval: true, workerData: OBJECT_ARGS });

    let methodsProxy = {};
    let methods = Object.getOwnPropertyNames(OBJECT.prototype);

    let rid = 0;
    let requests = [];
    for (let mid in methods) {
      let methodId = methods[mid];
      methodsProxy[methodId] = function () {
        return new Promise((resolve, reject) => {
          rid++;
          requests[rid] = { resolve: resolve, reject: reject };
          instance.postMessage({ method: methodId, arguments: Array.from(arguments), rid: rid });
        });
      };
    }

    instance.on('message', function (data) {
      if (data.rid) {
        if (data.valid) requests[data.rid].resolve(data.response);
        else requests[data.rid].reject();
        delete requests[data.rid];
      }
    });

    return methodsProxy;

  }

}

module.exports = WrapWorker;
回答如下:
// wrap-worker.js
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;

更多推荐

有没有办法将 node.js 类转换为 worker,以便它可以在单独的线程中执行?

本文发布于:2024-05-31 02:32:52,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1771182.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:它可以   没有办法   线程   转换为   node

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!