【问题标题】:Angular2/Rxjs HTTP Catch Asynchronous Transform IssueAngular2/Rxjs HTTP Catch 异步转换问题
【发布时间】:2017-04-01 20:03:16
【问题描述】:

我正在尝试在 Angular 2 中调用 HTTP Post 方法来检索 PDF 文件,因此我将 ResponseContentType 设置为 Blob,如下所示:

let headers = new Headers({
        'Content-Type': 'application/json',
        'ApplicationName': 'ControlEnroll',
        'Accept': 'application/pdf'
    });
let options = new RequestOptions({
        headers: headers,
        responseType: ResponseContentType.Blob
    });

现在,post() 调用成功时我没有问题,但是当它是错误时,我在提取从我的 WebAPI 方法返回的错误消息时遇到问题,因为它被包装在一个 Blob 中。

由于这是 Angular 2,我的 post() 调用和结构现在看起来像这样:

return this.http.post(postUrl, {
        // ... some body parameters here ...
    }, options)
        .map(resp => {
            let blob: Blob = resp.blob();
            // Use the file-save library to persist this to disk.
            window['saveAs'](blob, 'File.pdf');

            return resp;
        }).catch(error => {
            // What to do?
        });

问题出在catch() 方法中,我知道提供的error 是一个包含Blob 主体的响应对象。我知道从 Blob 对象中提取文本的唯一方法是使用 FileReader 和事件侦听器,如下所示:

let body = error.json();
let reader = new FileReader();

reader.addEventListener('loadend', function () {
    console.log(reader.result);
});

reader.readAsText(body);

但是,这不会立即发生;它是一个事件监听器。然而,catch() 必须 [likey] throw 是某种外部可观察到的错误,对吧?我如何处理这个catch() 方法,让我将字符串从Blob 中拉出,同时允许其他人订阅整个方法并使用正常的subscribe(successFn, errorFn) 结构?有可能吗?

【问题讨论】:

    标签: angular try-catch rxjs angular2-observables


    【解决方案1】:

    传递给catch 运算符的选择器函数可以返回一个可观察对象,该可观察对象将用于在发生错误时继续可观察对象链。

    因此,您的选择器函数可以返回一个等待来自FileReaderloadend 事件的可观察对象,然后在您从 BLOB 中读取的消息中引发错误。像这样的:

    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/observable/fromEvent';
    import 'rxjs/add/operator/do';
    
    ...
    .catch(error => {
      let reader = new FileReader();
      let loadend = Observable.fromEvent(reader, 'loadend');
      reader.readAsText(error.blob());
      return loadend.do(() => { throw new Error(reader.result /* or whatever */); });
    })
    

    【讨论】:

    • 非常感谢!我相信我需要在 lambda 子句中的示例 sn-p 的底部使用一组大括号 {},因为如果没有它们,它就无法工作,但否则这正是我所缺少的。我没有意识到 Observables 有一个 fromEvent 包装器来将事件转换为 Observable,而 do 方法允许 throw 稍后发生是一种享受。在 Promises 上花了很长时间之后,我仍然掌握了这些 Observables 的窍门,但这很棒。再次感谢。
    • 不用担心。添加了{}
    • 顺便说一句,您应该检查error 上是否存在blob 方法。例如,如果没有连接,如果您收到无响应错误,我不会感到惊讶,可以这么说。在这种情况下,您可能只想重新抛出收到的错误等。
    猜你喜欢
    • 1970-01-01
    • 2021-10-03
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 2017-10-13
    • 2016-10-31
    相关资源
    最近更新 更多