解決策を見つけた状況がありますが、満足していません。よりエレガントなソリューションを見つけようとしています。基本的に次のようなライブラリ:
- リクエストを送信し、レスポンス ストリームが正常に返されたときに完了コールバックを呼び出します
- 応答のストリームをデコードしますが、ストリームのデコード エラーがあります。面倒なエンコーディングなしでリクエストを再試行できるため、エラーは回復可能です。
概念としては単純です。エンコーディングを無効にし、再帰的にリクエストを再試行します。ただし、ストリームは一度に消費されない場合があります。クライアントコードに戻されるか、特定の方法でそれを消費するメソッドによってラップされる場合があります: バッファに保存するか、ファイルに保存します。したがって、ストリームを取得して処理を続行するための OK を与えるメソッドとしても知られる「内部ラッパー」と、ストリームを消費する「外部ラッパー」 (コード例の saveBuffer() ) を使用します。気になることを説明するコードをいくつか書きました。
var Request = function (options) {
this.options = options;
};
Request.prototype.send = function (callback) {
this.stream = createStream(function () {
callback(null, success); // completion callback
});
this.stream.pause();
};
// save the stream as Buffer
Request.prototype.saveBuffer = function (callback) {
var self = this;
this.stream.on('error', function (err) {
// unfortunately this err does not appear in this.send
// as it is a stream decoding error that happens in
// edge cases after the stream is passed back successfully
if ("recoverable error") {
// this is the piece of code that bothers me
self.options.disableTroublesomeEncoding = true;
self = new Request(self.options);
self.send(function (err, res) {
if (err) {
callback(err);
return;
}
self.saveBuffer(callback);
});
return;
}
callback(err);
});
this.stream.on('success', function () {
callback(null, self.success());
});
this.stream.resume();
}
Request.prototype.success = function () {
return {
code: this.stream.code //, etc
}
};
// client code
var req = new Request(options);
req.send(function (err, res) {
// if no error, continue
req.saveBuffer(function (err, success) {
// handle error or success
// success is different than req.success()
// for recoverable errors
});
});
デコード エラーが発生したときにクライアント コードが既に saveBuffer() にあるため、内部で新しい Request インスタンスを作成します。それが send() を再発行する唯一の簡単な方法でした。基本的に、新しいインスタンスを self (ここで self = this) に割り当てることで、内部的に適切に機能します。適切な成功ステータスを取得するには、それを「外部コールバック」の完了コールバックに渡す必要があります。これは私を悩ませていることです: req.success() は、内部で作成された Request オブジェクトの状態を反映していないため、間違った値を持っていますが、デコードに失敗した最初のリクエストによって返された値です。
元のオブジェクトを指すのではなく、内部で作成されたオブジェクトの状態を req.success() に返すことは可能ですか?