RxJS将catch()添加到已被共享的Observable中

时间:2017-07-18 22:15:00

标签: angular http rxjs

在$ 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 gets executed twice我发现我需要分享()结果。

这可以解除多个调用,但现在我的 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

任何人都知道我可以同时分享()捕捉(扔...)吗?

2 个答案:

答案 0 :(得分:2)

正如我对@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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您在问题中包含的第二个选项会将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>