Node.js中的内联子进程

时间:2018-05-15 16:37:27

标签: javascript node.js parallel-processing web-worker child-process

我熟悉浏览器中的Web Workers,并认为Node.js相当于做

const worker = new Worker('./worker')

const worker = child_process.fork('./worker')

API有点不同,它们的工作方式并不完全相同,但最终Web Workers和Child Processes似乎都做了大致相同的事情;允许您并行运行JavaScript代码。

现在,可以通过Web Workers完成这个简洁的事情,而不是通过传递包含工作代码的文件的路径/ url来创建Worker,您可以传递实际的函数。这可以通过这个简单的三线函数来实现:

function createWorker(fn) {
  var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
  var url = URL.createObjectURL(blob);

  return new Worker(url);
}

这允许您在主/主/父(无论你想称之为)文件中内联编写工作代码,如下所示:

var myWorker = createWorker(function (e) {
  self.postMessage(e.data.toUpperCase());
});

myWorker.onMessage = function (e) {
  console.log(e.data); // HELLO FROM AN INLINE WORKER!
}

myWorker.postMessage('hello from an inline worker!')

问题
如何使用Node.js子进程实现相同的功能?我无法通过查看文档来判断您是否可以将模块路径以外的内容传递给child_process.fork,或者是否有其他方法可以实现我想要的内容;编写内联子进程。

更新
我根据@Bergi在评论中的建议尝试了以下内容:

const fileSync = require('tmp').fileSync;
const writeFileSync = require('fs').writeFileSync;
const fork = require('child_process').fork;

function createWorker(fn) {
  const tmpobj = fileSync();
  writeFileSync(tmpobj.name, fn.toString()); 

  return fork(tmpobj.name);
}

var myWorker = createWorker(function (e) {
  process.send(e.toUpperCase());
});

myWorker.on('message', function (e) {
  console.log(e); // HELLO FROM AN INLINE WORKER!
})

myWorker.send('hello from an inline worker!');

唉,我收到以下错误:

C:\Users\phili\AppData\Local\Temp\tmp-165566BgqUKKM5yjR.tmp:1
(function (exports, require, module, __filename, __dirname) { function (e) {
                                                                       ^

SyntaxError: Unexpected token (
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:616:28)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

我担心我不在这里。知道发生了什么以及如何让它发挥作用吗?

2 个答案:

答案 0 :(得分:1)

以下是最终为我工作的内容:

const fileSync = require('tmp').fileSync;
const writeFileSync = require('fs').writeFileSync;
const fork = require('child_process').fork;



function createWorker(fn) {
  const tmpobj = fileSync();
  writeFileSync(tmpobj.name, `process.on('message', ${fn.toString()})`); 

  return fork(tmpobj.name);
}

var myWorker = createWorker(function (e) {
  process.send(e.toUpperCase());
});

myWorker.on('message', function (e) {
  console.log(e); // HELLO FROM AN INLINE WORKER!
})

myWorker.send('hello from an inline worker!');

感谢@Bergi帮助他解决这个问题。

答案 1 :(得分:1)

使用if exec </dev/tty; then read Input **OR** <call your process which takes input> fi ,现在实际上有可能通过内联代码创建线程,而无需临时文件(如snowfrogdev所示)。

worker_threads

在此示例中,将const { Worker } = require("worker_threads"); new Worker(`console.log(require("process").env.HOME)`, { eval: true }); 设置为eval也允许使用nodejs内置插件。