【问题标题】:Chain 3 or more dependent observables链 3 个或更多依赖的 observables
【发布时间】:2019-04-22 17:44:41
【问题描述】:

我知道在here 之前有人问过这个问题。但是接受的解决方案对我不起作用,或者我无法很好地理解它。

我正在使用 ng-7 我有简单的用例:

我有 2 个 API,第 2 个取决于第 1 个的响应。 我订阅了第一个 API 的结果,然后使用管道订阅了第二个 API 结果。

我的代码如下所示;

this._SomeService
        .addUserToDb(payload)
        .pipe(
          map(res => res),
          mergeMap(db1Response =>
            this._SomeService.addUserToDb2(db1Response
            )
          ),
          catchError(errodb1 => {

            return Observable.throw(new 
            Error(errorSso));
          })
        )
        .subscribe(
          resDb2 => {
              // Here I get response of addUserToDb2
          },
          errDb2 => {


          }
        )

现在在订阅第二个 API 响应之前,我想订阅另一个 observable 说:

this._tokenService.getToken.pipe(

)

并且想在服务 2 中使用它的响应。 这样:

API1 => 令牌 => API2

请建议如何实施。

更新:

我尝试实现,下面是我的实现:

  this._service.addUserToDB1(payload).pipe(
          map(resp => this.resDB1 = resp) // Adding to global variable because I need this response while subscribing to DB2 service.
          ,mergeMap(resdb1=>this._tokenService.getToken.pipe(
            mergeMap(token => this._service.addUserToDb2(
              this.resDB1,
              this.organizationId,
              this.practitionerId,
              token
            ),
            catchError(errorToken => {

              return Observable.throw(new Error(errorToken));
            })),
            )
          ),
          catchError(errordb1 => {

            return Observable.throw(new Error(errordb1));
          })

      ).subscribe (
        resdb2Response =>
        {

        },
        errdb2 => {

        }
      )

有人可以验证上述实现是否正确或建议正确的方法吗?

【问题讨论】:

    标签: observable rxjs6 angular7 rxjs-pipeable-operators


    【解决方案1】:

    mergeMap 操作符在这里很好,因为 Api 请求发出 1 个事件然后完成,但准确地说 请使用 switchMap 或 concatMap 而不是 mergeMap。如果您有兴趣,也请查看有关这些运算符的这篇文章。 RxJs Mapping Operators: switchMap, mergeMap, concatMap

    至于您的代码块,我会建议类似的内容:

    this._service.addUserToDB1(payload).pipe(
      catchError(errordb1 => {
        // do something with error if you want
        return Observable.throw(new Error(errordb1));
      }),
      tap(resp => this.resDB1 = resp),
      switchMap(resdb1 => this._tokenService.getToken),
      catchError(errorToken => {
        // do something with error if you want
        return Observable.throw(new Error(errorToken));
      }),
      switchMap(token => this._service.addUserToDb2(
        this.resDB1,
        this.organizationId,
        this.practitionerId,
        token
      )),
      catchError(errordb2 => {
        // do something with error if you want
        return Observable.throw(new Error(errordb2));
      }),
    ).subscribe(
      resdb2Response => {
    
      },
      anyError => {
        // any of the errors will come here
      }
    )
    
    • tap() 操作员就像只是做某事,而不是更改任何已发出的事件。当您只想做某事而不是转换发出的事件时,更喜欢点击地图。

    【讨论】:

    • Goga Koreli 非常感谢您的回答。我有一个查询,在“anyerror”中,我们将收到来自 this._service.addUserToDb2 的错误消息?如果是,那么为什么我们有用于 errordb2 的 cathError 块?
    • @Simer 您会收到来自this._service.addUserToDb2( 的错误,但也会收到来自this._service.addUserToDB1 的错误,所以如果您想编写逻辑,无论出现哪个错误,这里都是合适的。这就是为什么catchError(errordb2 => { 仍然存在的原因,以便您可以针对该错误编写特定的逻辑。如果您不想要该案例的特定逻辑,您可以删除该 catchError
    • 好的,再次感谢!那么我们将在 'anyError => { // 任何错误都会出现在这里 }' 中收到哪个错误?我们不会只在那里收到 _service.addUserToDb2 错误吗?
    • 不仅是 1 个特定的,而是所有的:errordb1、errorToken 或 errordb2,因为当错误发生时,您不仅会消耗错误,还会重新抛出错误,例如在 @ 987654328@。因此,在 subscribe 作为第二个参数,我们传递了 onError(err) 函数,当 Observable 中抛出错误时,运行时将调用该函数。所以 Observable 中抛出的任何错误最终都会到达这里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    • 2021-07-12
    • 2019-02-03
    • 2021-01-16
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    相关资源
    最近更新 更多