2

LevelUP Documentation には、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)

実際の問題は、イベント 'data' () を使用するときのメモリ使用量に関するものです。次に、stream.Transform を作成し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 オブジェクトを出力します。一方、 yourはバイトモードの書き込み可能なストリームです。入力としてバイトのみを受け取るため、イベント. できることは、javascript オブジェクトを入力として受け取り、文字列化されたバージョンを出力するTransform ストリームを作成することです。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);

オブジェクトを入力として受け取り、バイトを出力する変換ストリームを作成することに注意してください。詳細については、ドキュメントを参照してください。

ただし、平準化されたストリームをリクエストにパイプすることで解決しようとしている特定の問題について詳しく教えていただく必要があります。上記の解決策はあまり良い解決策ではありません。

第 3 に、使用時にメモリ リークが発生しませんでした.on('data')。このリスナーを追加すると、ストリームがフロー モードに変換されます。これは、可能な限り高速にデータを出力することを意味します。.pause()およびメソッドをいつでも使用して.resume()、ストリームを停止および再開できます。Readableしかし、新しい v0.10 ストリーム インターフェイス (別名、 streams2) を使用するWritableと、この問題に対処するのに役立ちTransformます。

于 2013-11-29T21:16:19.750 に答える