我有一个执行一些冗长计算的服务器。所以我让调用的文件parser.js在工作线程中运行。
现在,parser需要 httprequest对象(来自 http 模块),因为根据请求参数/正文,parser可能需要访问request.
这就是为什么我不能将请求的特定参数放入workerData. 物业parser需求由客户决定。
请求对象具有功能并且具有循环引用。
JSON.stringify不会工作,workerData也不能有功能
我需要在不破坏循环引用的情况下以某种方式删除这些函数。
尝试过的解决方案
我想出了这个
<file common.js>
1 | const objectHistory = [];
2 | function rmObjFunctions(obj) {
3 | for (const key in obj) {
4 | if ((typeof obj[key]).toLowerCase() == 'function') obj[key] = null;
5 | else if ((typeof obj[key]).toLowerCase() == 'object') {
6 | if (objectHistory.indexOf(obj[key]) != -1) continue;
7 | objectHistory.push(obj[key]);
8 | rmObjFunctions(obj[key]);
9 | }
10 | }
11 | return obj;
12 | }
上述功能适用于
const obj = {
a: '1',
b: '2',
c: '3',
d: {
a: 'a',
b: 'b',
c() {
console.log('Hi');
},
},
e: '5'
};
obj.f = obj;
console.log(rmObjFunctions(obj));
输出
<ref *1> {
a: '1',
b: '2',
c: '3',
d: { a: 'a', b: 'b', c: null },
e: '5',
f: [Circular *1]
}
它对服务器不起作用
代码
const server = HTTP.createServer(function(req, res) {
let statusCode = 200;
let output = '';
try {
const workerData = {
resource_root,
LABEL1: req: rmObjFunctions(req),
};
const worker = new WorkerThreads.Worker(__dirname + '/parser.js', { workerData });
const timeout = setTimeout(function() {
worker.terminate();
output += 'execution timed out after 10 seconds';
}, 10000);
worker.on('message', function([ statusCode, response ]) {
res.statusCode = statusCode;
output += response;
});
worker.on('error', function(error) {
res.statusCode = 500;
output += String(error.stack);
});
worker.on('exit', function(exitcode) {
clearTimeout(timeout);
res.end(output);
});
} catch (error) {
res.statusCode = 500;
LABEL2: res.end(output);
}
});
错误在LABEL2
上面的代码出错了LABEL2,说res.end isn't a function。运行typeof res.end返回object而不是function.
注释掉LABEL2会导致错误LABEL1。
表示rmObjFunctions(req)损坏的response对象。
错误在LABEL1
node:net:731
return this._getpeername().address;
^
TypeError: this._getpeername is not a function
at Socket.remoteAddress (node:net:731:15)
at rmObjFunctions (common.js:4:24)
at rmObjFunctions (common.js:8:13)
笔记:
使用修改 httprequest对象rmObjFunctions(req)也会损坏该response对象。
你可以像我做的那样捕捉上面的错误,然后在 catch 块上,做res.end()它会告诉你end不是一个函数。
如果typeof res.end它会输出object,则不会function。