Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/405.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用节点变换将一个对象变换为另一个对象_Javascript_Node.js_Typescript_Node Streams_Transform Stream - Fatal编程技术网

Javascript 如何使用节点变换将一个对象变换为另一个对象

Javascript 如何使用节点变换将一个对象变换为另一个对象,javascript,node.js,typescript,node-streams,transform-stream,Javascript,Node.js,Typescript,Node Streams,Transform Stream,我不熟悉节点流,并试图弄清楚为什么事情不能按预期进行。我只是在练习,想做一个愚蠢的转变 interface MyTransformStreamOptions { [key: string]: any } class MyTransformStream extends Transform { constructor(options) { options.readableObjectMode = true; options.writableObjectMode = true

我不熟悉节点流,并试图弄清楚为什么事情不能按预期进行。我只是在练习,想做一个愚蠢的转变

interface MyTransformStreamOptions {
  [key: string]: any
}

class MyTransformStream extends Transform {
  constructor(options) {
    options.readableObjectMode = true;
    options.writableObjectMode = true;

    super(options);
  }

  _transform(chunk, encoding, callback) {
    console.log('encoding: ' + encoding);

    // chunk should be an object here, due to
    // readableObjectMode = true right?

    const newObj = {};

    for (const [key, value] of Object.entries(chunk)) {
      console.log(`[key, value]: [${key}, ${value}]`);
      newObj['aa' + key] = 'bb' + value;
    }

    callback(null, newObj);
  }
}

const myTransformStream = new MyTransformStream({} as MyTransformStreamOptions);

process.stdin
  .pipe(myTransformStream)
  .pipe(process.stdout);
最后,我运行脚本并通过stdin输入:

{ car: 'honda', truck: 'mazda' }
我也试过:

"{ car: 'honda', truck: 'mazda' }"
但是循环将块视为字符串而不是对象。因此,我看到的输出如下:

[key, value]: [0, 123]
[key, value]: [1, 32]
...etc...
我尝试了以下各种组合:

options.readableObjectMode = true/false;
options.writableObjectMode = true/false;
以及在
\u transform()
中使用:

const obj = JSON.parse(chunk.toString());
但是,
obj
从来都不是对象,而是字符串

我的目标是将一个对象接收到我的转换流中,修改它,然后输出它。但我只能处理无法转换为对象的字符串,即使使用
JSON.parse()

我哪里出了问题

更新-部分解决方案

问题在于我使用了
JSON.parse()
。我试图分析:

{ car: 'honda', truck: 'mazda' }
这是有效的JS,但不是有效的JSON,duh

然而,更大的问题仍然存在。我已经将转换流设置为:
writeableobjectmode=true
,但是当我这样做时:

callback(null, newObj);
我得到一个错误:

TypeError:无效数据,区块必须是字符串或缓冲区,而不是对象

如果我这样做:

callback(null, JSON.stringify(newObj));
一切如期进行


但是,如果我已经在对象模式下设置了内容,那么如果不进行字符串化,这难道不应该工作吗?

对象模式不会将流从缓冲区(它是缓冲区而不是字符串)转换为对象,它只允许数据类型为缓冲区或字符串以外的类型。您需要使用转换流将stdin缓冲区转换为以下对象:

const ndjson = require('ndjson');

. . .

process.stdin
  .pipe(ndjson.parse())
  .pipe(myTransformStream)
  .pipe(process.stdout);

因此,我的代码的主要问题是使用
stdin
stdout
。它们是以字符串/缓冲区模式运行的流。按原样使用它们,将stdin管道传输到流将以字符串/缓冲区模式而不是对象模式进行。这同样适用于标准输出

我通过在对象模式下创建一个可读流来测试我的假设,该流模拟我通过
\u read()
方法输入的stdin输入,然后让我的转换流将块转换为可读流通过管道传入的对象

到标准输出的管道仍然失败,因为它接受开箱即用的对象。我通过创建另一个转换流来确认这一点,该转换流通过
JSON.stringify()
将对象简单地转换为字符串,然后stdout又高兴了


我在“读/写对象模式”方面遇到的所有问题都是因为我在转换流的两侧都有stdin和stdout。

谢谢您的提示,但使用ndjson并不能改变我看到的行为。另外,关于作为缓冲区的流,vs字符串等,来自节点docs:chunk | |要转换的块。将始终是缓冲区,除非decodeStrings选项设置为false或流以对象模式运行。在同一文档页面的其他地方:Node.js API创建的所有流都只在字符串和缓冲区(或Uint8Array)对象上运行。但是,流实现可以与其他类型的JavaScript值一起工作。