最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

网站源码admin29浏览0评论

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

有没有办法将 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;
发布评论

评论列表(0)

  1. 暂无评论