Node.js 子进程中的数据丢失

Data loss in Node.js child process

我试图将数据(作为对象)发送到 Node.js 中的子进程,但是,我的所有正则表达式在传输过程中都丢失了。

var arguments = {
    something: { 
       name: 'test',       
       age: 28,
       active; true          
    },
    otherThing: 'some string',
    regex: /test/i,
    regex2: new RegExp('test')
};

var child = cp.fork(path.join(__dirname, 'child.js'));

child.on('message', function (data) {
   console.log(data);
});

child.send(arguments);

在 child.js 文件中,我在顶部有这个:

process.on('message', function () {
   console.log(arguments); // This is where the data has changed
});

当日志从子进程输出时,arguments 对象看起来像这样:

{
    something: {
        name: 'test',
        age: 28,
        active: true
    },
    otherThing: 'some string',
    regex: {},
    regex2: {}
}

到目前为止无法在其他地方找到任何关于为什么会发生这种情况的信息,有什么想法吗?

您可以将正则表达式存储为字符串,例如

myRegex.string = "/test/";
myRegex.modif = "i";

发送到child然后像

一样使用
new RegExp(myRegex.string, myRegex.modif);

因为它们是完全独立的 JavaScript 进程,所以您不能发送对象。当您传递一个对象时,它会序列化为 JSON 并由子对象解析。 (参见 the docs。)

JSON 不支持序列化正则表达式对象。 (尝试通过您的控制台输入 JSON.stringify(/abc/)——您会返回 "{}"。)

要在 JSON 对象中包含正则表达式,您可以使用 json-fn 模块。它支持序列化函数、日期和正则表达式。 (实际上是由于我提出的一个问题,他们添加了正则表达式支持。:))

然后您可以执行以下操作:

var JSONfn = require('json-fn');
var arguments = {
    something: { 
       name: 'test',       
       age: 28,
       active; true          
    },
    otherThing: 'some string',
    regex: /test/i,
    regex2: new RegExp('test')
};

var child = cp.fork(path.join(__dirname, 'child.js'));
});

child.send(JSONfn.stringify(arguments));

和:

var JSONfn = require('json-fn');
process.on('message', function (data) {
   console.log(JSONfn.parse(data))); // This is where the data has changed
});

我尝试了 json-fn,但字符串化的 Date 对象没有恢复为 Date。此模块 JSON4Process 将对象的类型 Date、RegExp、Function、Set 和 Map 的属性字符串化,同时将对象维护为 javascript 对象。如果使用fork,则无需对整个对象进行字符串化,直接发送即可。

const { fork } = require('child_process');
const JSON4Process = require('json4process');

let obj = {
    date: new Date(),
    regex: new RegExp(/regex/g),
    func: () => console.log('func')
}

obj = JSON4Process.stringifyProps(obj);

const child = fork('child.js');
child.send(obj);

然后在另一个文件中解析属性:

process.on('message', data => {
    let obj = JSON4Process.parseProps(data);
});

如果您需要使用 spawn 或 exec,您可以使用默认的 JSON.stringify 在修改后的对象上使用 json4process:

let newObj = JSON.stringify(JSON4Process.stringifyProps(obj));
let originalObj = JSON4Process.parseProps(JSON.parse(newObj));