如何在levelup(node.js)中使用管道?

时间:2013-11-29 20:59:35

标签: node.js stream leveldb

LevelUP文档说明pipe()可以使用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()

实际问题是关于使用事件'data'()时的内存使用情况。然后我尝试做一个流。转换并使用 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); 来做我需要的事情。事件发生器中的内存泄漏是一个问题:https://github.com/rvagg/node-levelup/#pipes-and-node-stream-compatibility

更新

我试过@ paul-mougel没有成功。不调用错误事件的功能,并且它崩溃了。 这是代码的一部分:

{{1}}

1 个答案:

答案 0 :(得分:8)

有很多事情要考虑。

首先,您收到此异常是因为您没有收听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()object mode中创建了一个可读的流(请参阅source):它将输出javascript对象。另一方面,response是字节模式下的可写流:它只需要字节作为输入,因此error事件。您可以做的是创建一个Transform stream,它将javascript对象作为输入并输出其字符串化版本:

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);

请注意,我们创建一个转换流,将对象作为输入和输出字节。有关详细信息,请参阅the documentation

但是,你必须告诉我们更多关于你试图解决的具体问题,方法是将水平流加工成一个请求:上述解决方案不是一个很好的解决方案。

第三,使用.on('data')时没有遇到内存泄漏。添加此侦听器会将流转换为flowing mode,这意味着它将尽快输出数据。您始终可以使用.pause().resume()方法停止并重新启动流。但是使用新的v0.10流接口(又名streams2)可以帮助您解决这个问题,因为ReadableWritableTransform类会为您处理所有这些问题。