所以我通常会这样写我的http请求
服务
getData(){
return this.http.get('url')
}
组件
getTheData() {
this.service.getData().subscribe(
(res) => {
//Do something
},
(err) => {
console.log('getData has thrown and error of', err)
})
但是在浏览Angular文档时,他们似乎在服务中格式化了
getHeroes(): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl)
.pipe(
catchError(this.handleError('getHeroes', []))
);
}
这个隐含的上行空间是什么,因为它对我来说似乎很冗长,而且我个人从来就不需要传达我的错误。
答案 0 :(得分:1)
根据Angular团队
““ handleError()方法报告错误,然后返回无害的结果,以便应用程序继续运行”。
由于每种服务方法都返回不同类型的Observable结果,因此catchError中的函数(例如handleError())采用类型参数,因此可以返回安全值作为应用程序期望的类型。
答案 1 :(得分:1)
使用catchError
的一个主要好处是
将整个数据检索逻辑(包括所有在显示过程中可能发生的错误)与数据的呈现分开。
组件仅应关心数据(无论是否存在)。他们不应该关心如何检索数据的细节,也不必关心数据检索过程中可能出错的所有事情。
组件不应该直接获取或保存数据,它们当然 不应故意提供虚假数据。他们应该专注于呈现 数据并委托对服务的数据访问。 [Angular tutorial]
假设您的数据是一个项目列表。您的组件将调用service.getItemList()
函数,并且由于它只关心数据,因此可以期望:
null
或undefined
您可以使用Component模板中的ngIf
轻松处理所有这些情况,并根据情况显示数据或其他内容。让Service函数返回一个“干净”的Observable,该Observable仅返回数据(或null
),并且不会引发任何错误,这使您组件中的代码保持精简,因为您可以轻松地使用AsyncPipe订阅模板。
您的数据检索和错误处理逻辑可能会随时间变化。也许您要升级到新的Api,突然不得不处理其他错误。不要让您的组件为此担心。将此逻辑移至服务。
从组件中删除数据访问权限意味着您可以改变主意 随时实施,而无需涉及任何组件。他们不 了解服务的运作方式。 [Angular tutorial]
处理错误是数据检索逻辑的一部分,而不是数据表示逻辑的一部分。
在数据检索服务中,您可以使用catchError
运算符来详细处理错误。也许您想对所有错误执行某些操作,例如:
将其中的一些内容移至this.handleError('getHeroes', [])
函数中可以避免代码重复。
将错误报告给控制台后,处理程序将构造一个用户 友好的消息,并向应用程序返回安全值,以便它可以保持 工作。 [Angular tutorial]
有时您还需要从新组件调用现有Service函数。在Service函数中使用错误处理逻辑可以简化此操作,因为从新Component调用函数时,您不必担心错误处理。
因此归结为将数据检索逻辑(在Services中)与数据表示逻辑(在Components中)和将来扩展应用程序的简便性分开。
答案 2 :(得分:0)
只是碰到了这一点,以为我会更新自己的发现以更好地回答我自己的问题。
虽然从组件中抽象出错误处理逻辑的要点是一个完全有效的点,而最主要的要点是一个原因,但还有其他一些原因使得catchError不仅可以使用订阅错误方法来处理错误,还可以使用。 / p>
主要原因是catchError允许您处理http.get或在管道方法内发生错误的第一个运算符返回的observable,即
this.http.get('url').pipe(filter(condition => condition = true), map(filteredCondtion => filteredCondition = true), catchError(err, return throwError(err)).subscribe(......)
因此,如果这些运算符中的任何一个由于某种原因而失败,则catchError会捕获从该错误返回的可观察到的错误,但是使用catchError遇到的主要好处是可以防止可观察到的流在事件中关闭错误。
使用throwError
或catchError(err throw 'error occcured')
将导致订阅方法的错误部分被调用,从而关闭可观察的流,但是像这样使用catchError
;
示例一-catchError(err, of({key:'streamWontError'})
//将返回of声明的可观察对象,从而发出需要在订阅上触发错误的情况
示例二-catchError(err, catchedObservable}
//实际上,如果发生错误,这实际上将尝试再次调用失败的可观察对象,从而再次阻止错误方法的调用。