【问题标题】:Trouble understanding how to handle errors and continue with subscription with RXJS无法理解如何处理错误并继续使用 RXJS 订阅
【发布时间】:2018-11-17 15:42:13
【问题描述】:

我对这个概念有很多困难。我有 2 种表格,可以通过同一个 xhr 调用来处理。所以我通过公共流发送表单提交并切换到 xhr 调用。我正在尝试使用 catchError 来处理任何 500,这确实有效(.publish(error) 调用会弹出一个带有错误消息的对话框),但随后订阅会立即完成!我认为这会不断地从 search$ 流中获取输入,直到我调用 this.search$.complete()(这发生在 componentDestroy 上)。关于 RXJS 的“捕捉并继续收听”,我错过了什么?

  this.search$.pipe(
      tap(() => this.pending = true),
      switchMap(criteria => this._dealer.search(criteria)),
      catchError(ErrorNotifierService.catchResponseErrorAsObservable)
    ).subscribe(response => {
      this.pending = false;
      if (ErrorNotifierService.isCaughtError(response)) {
        this._error.publish(ErrorNotifierService.getErrorNotification(response.error));
      } else {
        this.dsSearchResults.data = response;
      }
    }, () => console.log('subscribe errored'), () => console.log('subscribe completed?'));

【问题讨论】:

    标签: angular rxjs


    【解决方案1】:

    您需要将 catchError 移动到 switchMap 调用中,因为您已经想从切换的 observable 中“隐藏”错误。这可以简单地通过嵌套来完成:

    this.search$.pipe(
      tap(() => this.pending = true),
      switchMap(criteria => this._dealer.search(criteria)
        .pipe(catchError(ErrorNotifierService.catchResponseErrorAsObservable))
      )
    ).subscribe(…);
    

    您的代码的问题是,在您的情况下,switchMap 将切换到一个发出错误的可观察对象,从而结束订阅。我们希望将此错误映射到发射我们切换到该可观察对象之前,以便生成的流甚至永远不会看到错误。

    您可以找到代码的可运行在线示例here 和固定示例here

    【讨论】:

    • 完美。感谢您对原因的扩展解释。我需要花点时间来理解它,但我更改了我的应用程序以匹配您的示例,并且它完全按预期工作。
    • 基本上 switchMap 所做的就是每次收到一个值时,它都会订阅内部的 observable 并转发这些发射。如果出现新值时之前的内部订阅尚未完成,则它首先取消订阅。通过在此之外设置 catchError,此内部订阅将出错,这会导致 switchMap 将其转发到外部订阅。一旦 observable 出错,它就不能再发出。通过将 catchError 移到内部,只有内部的 observable 不能再发出,但外部的仍然可以,从而允许整个流继续运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    相关资源
    最近更新 更多