我遇到了一个解决问题的方法,但我并不满意。我正试图找到一个更优雅的解决方案。基本上是一个库:
作为概念,事情很简单:禁用编码,递归重试请求。但是,可能不会立即消耗流。它可以传递回客户端代码,也可以由以特定方式使用它的方法包装:将其保存到缓冲区或将其保存到文件中。因此,它使用“内部包装器”,即检索流并提供继续处理的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
});
});
我在内部创建一个新的Request实例,因为当解码错误命中时客户端代码已经在saveBuffer()中,这是重新发送send()的唯一简单方法。基本上,通过将新实例分配给self(其中self = this)在内部正常工作。为了获得正确的成功状态,我必须将它传递给“外部回调”的完成回调。这是困扰我的事情:req.success()具有错误的值,因为它不反映内部创建的Request对象的状态,但是初始请求返回的值无法解码。
是否可以让req.success()返回内部创建的对象的状态而不是指向原始对象?