指定rxjs可观察的“错误”处理程序的类型

时间:2019-06-10 11:34:35

标签: angular typescript rxjs

假设我有一些返回可观察值的操作。

this.loginService
  .post<IResponse>(url, { username, password })
  .subscribe(
    next => { /* I know the type of next */ },
    error => { /* Can I specify type of err, or is it always any? */ }
  );

我可以设置next的类型-在这种情况下为IResponse

error怎么样-我能以某种方式指定它的类型吗?还是总是any,我总是需要在处理程序中进行类型转换?

3 个答案:

答案 0 :(得分:3)

您可以使用括号来实现:

this.loginService
  .post<IResponse>(url, { username, password })
  .subscribe(
    (next: TypeOfYourResponse) => {...},
    (error: TypeOfYourErrorResponse) => {...}
  );

有关箭头功能的进一步阅读:

https://www.tutorialsteacher.com/typescript/arrow-function

https://basarat.gitbooks.io/typescript/docs/arrow-functions.html

答案 1 :(得分:2)

根据我的经验,从HTTP操作中产生可观察值的服务永远不会发出未捕获的HTTP错误。它在该服务的使用者中创建了许多样板代码,并迫使使用者处理HTTP特定问题。

我还认为服务应该捕获所有类型的错误,而只能捕获已知和预期的错误。要求应用程序本身使用错误拦截器处理极端情况。

export interface ILoginResponse {
   //...
}

export interface IServiceResponse<TType> {
   success: boolean;
   payload?: TType;
}

@Injectable()
export class LoginService {

   public login(options: any): Observable<IServiceResponse<ILoginResponse>> {
      return this.httpClient.post<ILoginResponse>('login', options).pipe(
          map(payload => ({success: true, payload})),
          catchError(err => {
              if(err instanceof HttpErrorResponse) {
                  // handle http errors here, maybe retry, update headers, etc..
                  return of({success: false});
              }
              // this error is unexpected, we don't know what to do
              // let the app interceptor handle it, but upstream observables
              // won't know what to do either. Our app has crashed...
              // You can return success false, but why handle this error?
              return throwError(err);
          });
   }
}

为什么要执行上述操作?

每当您使用发出未捕获错误的 route 解析器时,它都会失败路由转换。路由器将基本上崩溃。用户基本上只会看到一个空白页,因为解析器没有错误处理的回退。

以上内容仅捕获HTTP错误,因为这是我们认为应该抛出的唯一错误。另一种错误应视为错误。

如果组件调用此服务,则程序员在信任发射的值之前,应检查success的{​​{1}}标志。如果业务逻辑不在乎它是否失败,或者组件可以直观地向用户显示它无法执行HTTP请求,则可以对此进行过滤。无论哪种方式,HTTP错误响应都不会传递到应用程序错误拦截器。

这只是一种方法。人们对HTTP的处理完全不同。另一个答案可以正确回答您的问题。

答案 2 :(得分:2)

使用catchError运算符的另一种方法:

this.loginService
  .post<IResponse>(url, { username, password })
  .catchError<TypeOfYourErrorResponse>(() => // Your catch callback)
  .subscribe(
    next => { /* I know the type of next */ },
  );