サービスを呼び出すためのnodejsプロキシがあります。応答では、リクエストはサービスURLにパイプされます(返す前に応答を解析する場合は、正しい方法です)。問題は、JSON.parse(data)でパーサーが失敗することがあるということです。問題のデバッグ中に私が見たことは、解析されているデータが完全ではないということです(たとえサービスが正しく返されたとしても)。 私はパイプやストリームの経験があまりないので、なぜこれが失敗するのか分かりません。パイプレス応答の解析でチャンクされたデータが取得されることがあります
//Request setup
r.on('response', function(resp) {
if (resp.statusCode === 200) {
r.pipe(responseParser(config.get('service:url'))).pipe(res);
} else {
r.pipe(res);
}
});
//Parser module
var _ = require('lodash'),
stream = require('stream');
module.exports = function responseParser(url) {
var data = '',
parser = new stream.Transform({
objectMode: true
});
parser._transform = function (chunk, encoding, done) {
data += chunk.toString();
done();
};
parser._flush = function (done) {
if (data) {
var obj = mapValues(JSON.parse(data));
this.push(JSON.stringify(obj));
}
done();
};
function mapValues(data){
...
}
return parser;
}
私はまだすべてのデータチャンクが返される前にフラッシュが呼び出される理由は時々知らないが、私はそれを避けるためにやったことは、彼らが到着したとことを確認することで、チャンクを解析するだけですチャンクで私はマップする必要がある値の部分データを取得しません。チャンクに目標値の部分的な情報しか含まれていない場合は、それを削除して次のチャンクの先頭に追加します。このようにしてデータが解析されるので、すべてのデータが返されたときにのみflushが呼び出されるという事実に頼る必要はありません。
なぜパーサが閉じられた後に文字列を押すだけの場合は、 'objectMode:true'を使用していますか? – mscdex
残念ながら、それは私が解読しようとしている共有コードなので、私はちょうどそのように見えました。パーサーが閉じられた後に文字列を押すようなことはありません。それが原因だろうか? – Bianca
'this.push(JSON.stringify(obj));'は文字列をプッシュしています。 – mscdex