0

我有一种情况,我找到了解决方案,但我对此并不满意。我试图找到一个更优雅的解决方案。基本上是一个库:

  • 发送请求,成功返回响应流时调用完成回调
  • 解码响应的流,但存在流解码错误。该错误是可恢复的,因为可以在没有麻烦的编码的情况下重试请求

作为概念,事情很简单:禁用编码,递归重试请求。但是,流可能不会立即被消耗。它可能会被传递回客户端代码,或者它可能被以特定方式使用它的方法包装:将其保存到缓冲区,或将其保存到文件中。因此,它使用“内部包装器”,即检索流并为继续处理提供 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() 返回内部创建对象的状态而不是指向原始对象?

4

0 回答 0