将对象作为参数发送到分叉的Node.js进程

4

在主进程中使用 fork('./MyProcess.js',['foo']);,在子进程中使用 console.log(process.argv[2]); 将会把 foo 输出到我的控制台。

然而,在主进程中使用 fork('./MyProcess.js',[{myProp : 'bar'}]);,在子进程中使用 console.log(process.argv[2]); console.log(process.argv[2].myProp); 将会把[object Object](与预期一致)输出,但第二个日志输出是 undefined

这是为什么?我该怎么做才能得到想要的行为?


child_process.fork 期望 args 参数是一个字符串数组,但你提供了一个包含对象的数组。 - E net4
4个回答

7

将对象(json)通过命令行参数传递给子进程并不是一个好主意,因为命令行参数需要进行转义(不容易)。你有以下几个选择:

  1. 将JSON编码为十六进制,然后传递给子进程,虽然这样可以工作,但是你的子进程接口不够好。
  2. 将JSON保存到文件中,然后传递文件路径。
  3. 通过stdin将JSON传递给子进程。
  4. 作为消息将JSON发送给子进程,请参见https://nodejs.org/api/child_process.html#child_process_child_send_message_sendhandle_options_callback

谢谢,我会将其作为消息发送,因为在其他情况下我已经这样做了。 - Jonah
项目编号4的正确链接为https://nodejs.org/api/child_process.html#child_process_subprocess_send_message_sendhandle_options_callback。 - jatinder bhola

4

child_process.fork文档所述:

child_process.fork(modulePath[, args][, options])

args 字符串参数列表

如果执行 fork('./MyProcess.js',[{myProp : 'bar'}]),你会发现传递的是一个对象而不是字符串。这可能导致行为随着实现的不同而不同,但我在 Node.js v6.1.0 上测试发现该对象将被转换为字符串 '[object Object]'。该字符串不包含 myProp 属性,因此返回 undefined。

解决方法是只传递字符串:

fork('./MyProcess.js', ['bar']);

如果您关心命名参数,只需适当格式化它们(见下文),然后使用另一个包(例如yargs)或自己的解决方案进行解析。在这种情况下,您可以这样做:
fork('./MyProcess.js', ['--myProp=bar']);

为了完整起见,您可以将此代码添加至"MyProcess.js"文件中:

var argv = require('yargs').argv;
console.log('My prop is: ' + argv.myProp);

为什么不直接使用JSON.stringify一个对象呢?这就是我正在做的事情。:1 - LJD
1
@JudeDesir 这也是可能的。然而,对于命令行界面来说,这不是惯用语,因此我更喜欢在这里使用yargs。使用JSON或者使用进程间通道代替命令行参数,是传递大型或复杂对象的合理替代方案。 - E net4

1
选择 5,在 env 选项中设置键值对会更好。
// in parent process
fork('./some.js', {
  env: Object.assign(process.env, { HELLO: 'world' })
});
// in forked process <some.js>
console.log(process.env.HELLO);
// world

不要这样做!https://nodejs.org/api/process.html#processenv说:“在process.env上分配属性将隐式地将值转换为字符串。此行为已弃用。当值不是字符串、数字或布尔值时,Node.js的未来版本可能会抛出错误。” - Chris

1

你可以对你的对象进行base64编码:

const obj = { foo: 'bar', date: new Date() };
const encoded = Buffer.from(JSON.stringify(obj)).toString('base64');

fork('./MyProcess.js',[encoded]);

接收端:

const data = process.argv[2];
const decoded = JSON.parse(
  Buffer.from(data, 'base64').toString('utf-8')
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接