RxJS 将 catch() 添加到已共享的可观察量



我在$http调用期间在我的 Angular (4.0( 应用程序中使用以下代码。

return this.httpComponent.post(serviceUrl, request, args)
.map((res: any) => res.json() as R)
.catch((error: any) => Observable.throw(error.json().error || error.json().errorMessage || 'Server error'));

测试后,我意识到多个订阅多次触发请求。感谢这篇文章:Angular2 http.post 被执行两次,我发现我需要分享((结果。

这可以摆脱多个调用,但现在似乎我的catch((方法没有被击中。我希望我的catch((抛出错误。

我尝试了以下两个选项,但它们不起作用:

return this.httpComponent.post(serviceUrl, request, args)
.map((res: any) => res.json() as R)
.share()
.catch((error: any) => Observable.throw(error.json().error || error.json().errorMessage || 'Server error'));
return this.httpComponent.post(serviceUrl, request, args)
.map((res: any) => res.json() as R)
.catch((error: any) => Observable.throw(error.json().error || error.json().errorMessage || 'Server error') 
.share()); //This doesn't make sense since my catch() isn't returning an Observable

有人知道我如何同时分享((和捕捉(抛出...(吗?

正如我在对@cartant答案的评论中提到的,如果任何订阅者没有错误处理程序(即:不关心任何错误场景(,则会抛出异常,并且所有后续订阅者都不会被告知原始错误。

在我看来,这似乎是一个设计缺陷。这是例子(复制自@cartant的答案(

const source = Rx.Observable
.interval(500)
.map((value) => {
if (value === 2) {
throw new Error("Boom!");
}
console.log(`value: ${value}`)
return value;
})
.catch((error) => Rx.Observable.throw(new Error(`Re-thrown ${error.message}`)))
.share();
source.subscribe(
(value) => console.log(`subscription 1: ${value}`)
);
source.subscribe(
(value) => console.log(`subscription 2: ${value}`),
(error) => console.log(`subscription 2: ${error}`)
);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>

您在问题中包含的第二个选项将catch附加到Observable.throw。如果更正了此问题,您应该会看到您期望的行为:

const source = Rx.Observable
.interval(500)
.map((value) => {
if (value === 2) {
throw new Error("Boom!");
}
console.log(`value: ${value}`)
return value;
})
.catch((error) => Rx.Observable.throw(new Error(`Re-thrown ${error.message}`)))
.share();
source.subscribe(
(value) => console.log(`subscription 1: ${value}`),
(error) => console.log(`subscription 1: ${error}`)
);
source.subscribe(
(value) => console.log(`subscription 2: ${value}`),
(error) => console.log(`subscription 2: ${error}`)
);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs@5/bundles/Rx.min.js"></script>

最新更新