angular:捕获rxjs管道/合并映射序列中的错误

时间:2018-02-09 23:31:52

标签: angular rxjs

目前我的代码结构如下,并且效果很好:

// service:
getRequestA() { return this.http.get(someUrl) }
getRequestB(id) { return this.http.get(someUrl + id) }
getRequestC(id) { return this.http.get(someUrl + id) }
getAll() {
  return getRequestA()
    .pipe(
      mergeMap((resp) => {
        return this.getRequestB(resp.id)
      }),
      mergeMap((resp) => {
        return this.getRequestC(resp.id)
      })
    )
}

允许我在我的组件中执行此操作:

// component:
service.getAll().subscribe(resp => {
  // result of service.getRequestC()
}, error => {
  // error occurred in any 1 of the 3 http calls
});

这很好,因为我需要在开始下一次之前调用每个调用的结果,而我只关心最终结果。但是,现在我想知道3个http调用中哪个具体失败,以便向用户显示更好的错误。我已经尝试了很多东西,但无法在服务中抛出自定义错误,然后我可以在组件中区分它们。提前感谢任何建议!

1 个答案:

答案 0 :(得分:2)

这样的安排应该让你标记并重新抛出任何错误:

const tagError = (tag, error) => {
  error.tag = tag;
  return error;
};

getAll() {
  return getRequestA().pipe(
    catchError(error => { throw tagError("A", error); }),
    mergeMap(resp => this.getRequestB(resp.id).pipe(
      catchError(error => { throw tagError("B", error); })
    )),
    mergeMap(resp => this.getRequestC(resp.id).pipe(
      catchError(error => { throw tagError("C", error); })
    ))
  );
}

实际上,您可以更进一步,将tagError函数转换为可管道运算符:

const tagError = tag => catchError(error => {
  error.tag = tag;
  throw error;
});

getAll() {
  return getRequestA().pipe(
    tagError("A"),
    mergeMap(resp => this.getRequestB(resp.id).pipe(tagError("B"))),
    mergeMap(resp => this.getRequestC(resp.id).pipe(tagError("C")))
  );
}