2

LevelUP 文档说pipe()可以使用(https://github.com/rvagg/node-levelup/#pipes-and-node-stream-compatibility)。

我试过以下代码:

db.createValueStream().pipe(response)

但我做不到,我有一个错误:

events.js:72
        throw er; // Unhandled 'error' event
              ^
TypeError: Invalid non-string/buffer chunk
    at validChunk (_stream_writable.js:150:14)
    at Writable.write (_stream_writable.js:179:12)
    at write (_stream_readable.js:573:24)
    at flow (_stream_readable.js:582:7)
    at ReadStream.pipeOnReadable (_stream_readable.js:614:5)
    at ReadStream.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:408:10)
    at emitReadable (_stream_readable.js:404:5)
    at readableAddChunk (_stream_readable.js:165:9)
    at ReadStream.Readable.push (_stream_readable.js:127:10)

实际问题是使用事件“数据”()时的内存使用情况。然后我试着做一个流。转换并pipe()用来做我需要的。一旦事件发射器中的内存泄漏是一个问题:在 Node.js 中使用流时内存泄漏?

更新

我试过@paul-mougel 没有成功。错误事件的函数没有被调用,它崩溃了。这是一段代码:

    var rs = db.createValueStream();

    request.on('close', function(){
        rs.destroy();
        response.end();
    });

    rs.on('end', function(){
        response.end();
    });
    rs.on('error', function(err){
        console.err('READ STREAM ERROR:',err.message);
        response.end();
        rs.destroy();
    });

    response.on('error', function(err){
        console.log('RESPONSE ERROR:',err);
        rs.destroy();
    });

    rs.pipe(stringifier).pipe(response);
4

1 回答 1

9

有很多事情需要考虑。

首先,您会收到此异常,因为您没有收听该error事件。在流的情况下,请始终收听它,i) 将允许您记录问题 ii) 不会使程序崩溃。

var valueStream = db.createValueStream()
valueStream.on('error', function (err) {
  console.error('valueStream.on error ' + err.message);
});
valueStream.pipe(response);
response('error', function (err) {
  console.error('response error ' + err.message);
});

其次,在对象模式下db.createValueStream()创建一个可读流(参见源代码):它将输出 javascript 对象。另一方面,您是字节模式下的可写流:它只将字节作为输入,因此事件。您可以做的是创建一个转换流,它将 javascript 对象作为输入并输出它们的字符串化版本:responseerror

var stream = require('stream')
var stringifier = new stream.Transform();
stringifier._writableState.objectMode = true;
stringifier._transform = function (data, encoding, done) {
    this.push(JSON.stringify(data));
    this.push('\n');
    done();
}

valueStream.pipe(stringifier).pipe(response);

请注意,我们创建了一个将对象作为输入并输出字节的转换流。有关更多信息,请参阅文档

但是,您必须通过将水平流传输到请求中来告诉我们更多关于您尝试解决的具体问题:上述解决方案不是一个很好的解决方案。

第三,您在使用.on('data'). 添加此侦听器会将流转换为流动模式,这意味着它将尽可能快地输出数据。您始终可以使用.pause().resume()方法来停止和重新启动流。但是使用新的 v0.10 流接口(又名 stream2)可以帮助您处理这个问题,因为Readable,WritableTransform类会为您处理所有这些问题。

于 2013-11-29T21:16:19.750 回答