我不确定如何在使用 forkJoin 时获取特定 api 调用的异常消息
我的代码如下所示
reqs = [];
if (shouldUpdatePhone) {
reqs.push(this.customerService.updatePhone(phoneUpdateRequest))
}
if (shouldUpdateAddress) {
reqs.push(this.customerService.updateAddress(addressUpdateRequest))
}
forkJoin(reqs).subscribe(result => {
console.log('result :', result);
}, error => {
//How to get error message for particular api call?
});
如果一个/两个 api 由于某种原因失败。我应该如何决定哪个 api 抛出异常。
最佳答案
有一种方法可以处理 forkJoin
的错误,它不会阻止您使用此运算符。关键实际上是另一个答案的一部分。
是的,forkJoin
将在第一个错误时完成,您有点不知道它来自哪个 observable,但如果您处理内部 observable 中的错误,您可以轻松实现。
考虑你的代码的这个(缩小的)部分,与 @Explosion Pills answer 混合:
reqs: Observable<any>[] = [];
if (shouldUpdatePhone) {
reqs.push(
this.service.updatePhone(phone)
.pipe(
catchError((err) => {
// Handle specific error for this call
return of(undefined)),
}
)
);
}
if (shouldUpdateAddress) {
reqs.push(
this.service.updateAddress(address)
.pipe(
catchError((err) => {
// Handle specific error for this call
return of(undefined)),
}
)
);
}
然后,对于您的forkJoin
:
forkJoin(reqs).subscribe(result => console.log(result));
现在考虑两个 API 调用分别返回一个对象,例如 {phone: string}
和 {address: string}
。您的结果
将是:
[{phone: '123-456'}, {address: 'Happy Street, 123'}]
但是好吧,这是基本的 forkJoin
,错误处理部分在哪里?
假设您的一个调用失败了,返回的错误包含一个状态代码和一条消息,您希望同时了解这两者。
正如我所说,如果您在内部可观察对象中处理错误,forkJoin
将不会完成,这就是我们有
.pipe(
catchError((err) => {
// Handle specific error for this call
return of(undefined)),
}
)
如果您的第一次调用 (updatePhone) 失败,您的结果将是
[undefined, {address: 'Happy Street, 123'}]
因为您没有让 observable 消亡,并且在出错时返回了一个新的 Observable 并带有 return of(undefined)
。
这让您可以处理这样的错误(在 catchError
中):
catchError((err) => {
if (err.status === 409) {
// do something
}
return of(undefined)),
}
或者像这样
...
catchError((err) => {
return of({error: err, isError: true})),
}
...
forkJoin(...).subscribe(result => {
result.forEach(r => {
if (r.isError) {
// do something
}
});
});
您的所有 API 调用都将完成,您可以随时处理它,也可以等待所有 API 调用返回并仅处理返回错误的调用,这样您可以获得错误可能提供给您的任何信息,并且具体处理。
关于 Angular 6 : Error handling with forkJoin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51993575/