【问题标题】:How can I error handle chained http requests individually when using mergeMap in Angular?在 Angular 中使用 mergeMap 时,如何单独错误处理链接的 http 请求?
【发布时间】:2020-03-31 03:20:34
【问题描述】:

我在 Angular 中使用 mergeMap 链接 http 请求。链接的请求工作得很好——我遇到的问题是错误处理。我想根据哪个请求失败运行不同的逻辑。例如,如果第一个请求失败,我想console.log("failed on request1")。如果第二个请求失败,我想console.log("failed on request2")。该方法的(简化)代码如下所示:

  submitRequests(): void {
    this.service.request1()
        .pipe(mergeMap(result => {
          let resultId = result.id;
          return this.service.request2(resultId);
        }))
        .subscribe(() => { console.log("Both requests successful") },
                   err => {
                     // If failed on request1, console.log("failed on request1")
                    // If failed on request2, console.log("failed on request2")
                   });
  }

有谁知道如何在 Angular 中最好地实现这一点?

【问题讨论】:

    标签: javascript angular http angular-httpclient


    【解决方案1】:

    我认为你应该这样做:

    this.service.request1()
      .pipe(
        mergeMap(result => {
          let resultId = result.id;
          return this.service.request2(resultId).pipe(catchError(err => {
            // 1. You can handle the error and do some logic here
            // 2. Or you can pass some data in throwError and determine in subscribe (error callback) failed request 
    
            return throwError(resultId);
          }));
        }),
      ).subscribe(
        () => {},
        failedResultId => console.log(`Failure occured for: ${failedResultId}`)
      );
    

    希望对你有帮助;)

    【讨论】:

      【解决方案2】:

      我认为您可以像以前那样处理一次订阅中的错误。我们有错误回调,我们得到 HttpErrorResponse。其中有 url 属性,您可以从中区分哪个 API 失败。示例:

      this.postService.getPosts()
        .mergeMap(posts => {
          console.log("Posts: ", posts);
          return this.postService.getPost(posts[0].userId);
        }).subscribe(posts => {
          console.log("First Post: ", posts);
          this.postsDetails = posts;
          this.loading = false;
        },(error: HttpErrorResponse)=>{
          if(error){
            if(error.url=="https://jsonplaceholder.typicode.com/posts"){
              console.log("Error coming from 1st API");
            }else{
              console.log("Error coming from 2nd API");
            }
          }
        });
      

      如果error.url 与第一个请求的 API url 匹配,那么我们可以确认错误来自于此。否则它来自第二个 API 调用。

      演示:

      https://stackblitz.com/edit/angular-rxjs-operators-examples?file=src%2Fapp%2Fstackoverflow%2Fmerge-map-error%2Fmerge-map-error.component.ts

      https://angular-rxjs-operators-examples.stackblitz.io/stackoverflow

      希望这会有所帮助。

      【讨论】:

      • 是的,这是我想出的最佳解决方案,但我认为可能有更好的方法。请求的 URL 包含一些动态 ID,所以我最终只是想看看是否有子字符串匹配。感觉有点笨拙
      • 由于我们只有一个订阅,不知道有没有其他方法,我们可以区分两者。感谢您的回复。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多