Angular2/Rxjs HTTP捕获异步转换问题

Angular2/Rxjs HTTP捕获异步转换问题,angular,try-catch,rxjs,angular2-observables,Angular,Try Catch,Rxjs,Angular2 Observables,我试图调用Angular 2中的HTTP Post方法来检索PDF文件,因此我将ResponseContentType设置为Blob,如下所示: let headers = new Headers({ 'Content-Type': 'application/json', 'ApplicationName': 'ControlEnroll', 'Accept': 'application/pdf' }); let options = new

我试图调用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
    });
let body = error.json();
let reader = new FileReader();

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

reader.readAsText(body);
现在,我对
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()
方法中,我知道提供的
错误
是一个包含Blob主体的响应对象。据我所知,从Blob对象提取文本的唯一方法是使用文件读取器和事件侦听器,如下所示:

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

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

reader.readAsText(body);

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

传递给
catch
操作员的选择器函数可以返回一个可观测值,该值将用于在发生错误时继续可观测链

因此,您的选择器函数可以返回一个observable,它等待
FileReader
中的
loadend
事件,然后对从BLOB中读取的消息抛出一个错误。大概是这样的:

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

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

reader.readAsText(body);
从'rxjs/Observable'导入{Observable};
导入“rxjs/add/observable/fromEvent”;
导入'rxjs/add/operator/do';
...
.catch(错误=>{
let reader=new FileReader();
让loadend=Observable.fromEvent(读取器,'loadend');
reader.readAsText(error.blob());
返回loadend.do(()=>{抛出新错误(reader.result/*或其他任何*/);});
})

传递给
catch
操作员的选择器函数可以返回一个可观察值,该值将用于在发生错误时继续可观察链

因此,您的选择器函数可以返回一个observable,它等待
FileReader
中的
loadend
事件,然后对从BLOB中读取的消息抛出一个错误。大概是这样的:

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

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

reader.readAsText(body);
从'rxjs/Observable'导入{Observable};
导入“rxjs/add/observable/fromEvent”;
导入'rxjs/add/operator/do';
...
.catch(错误=>{
let reader=new FileReader();
让loadend=Observable.fromEvent(读取器,'loadend');
reader.readAsText(error.blob());
返回loadend.do(()=>{抛出新错误(reader.result/*或其他任何*/);});
})

非常感谢!我相信我需要在lambda子句中的示例代码段的底部有一组大括号{},因为如果没有大括号,它在我这一端是不起作用的,但除此之外,这正是我所缺少的。我没有意识到Observable有一个
fromEvent
包装器来将事件转换为Observable,而
do
方法允许以后发生
throw
。在花了很长时间在承诺上之后,我仍然掌握着这些观察的窍门,但这很好。再次感谢,不用担心。添加了
{}
。顺便说一句,您应该检查
错误上是否存在
blob
方法。例如,如果没有连接,可以说,如果出现无响应错误,我不会感到惊讶。在这种情况下,您可能需要重新抛出收到的错误,等等。非常感谢!我相信我需要在lambda子句中的示例代码段的底部有一组大括号{},因为如果没有大括号,它在我这一端是不起作用的,但除此之外,这正是我所缺少的。我没有意识到Observable有一个
fromEvent
包装器来将事件转换为Observable,而
do
方法允许以后发生
throw
。在花了很长时间在承诺上之后,我仍然掌握着这些观察的窍门,但这很好。再次感谢,不用担心。添加了
{}
。顺便说一句,您应该检查
错误上是否存在
blob
方法。例如,如果没有连接,可以说,如果出现无响应错误,我不会感到惊讶。在这种情况下,您可能需要重新抛出接收到的错误,等等。