Укажите тип обработчика «ошибки» rxjs наблюдаемой - PullRequest
3 голосов
/ 10 июня 2019

Предположим, у меня есть какая-то операция, которая возвращает наблюдаемое.

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 ]

3 голосов
/ 10 июня 2019

Вы можете использовать скобки для того, чего хотите достичь:

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

2 голосов
/ 10 июня 2019

Другой способ сделать это с помощью оператора catchError:

this.loginService
  .post<IResponse>(url, { username, password })
  .catchError<TypeOfYourErrorResponse>(() => // Your catch callback)
  .subscribe(
    next => { /* I know the type of next */ },
  );
2 голосов
/ 10 июня 2019

По моему опыту, сервис, который выдает наблюдаемые из операции 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 , который выдает неперехваченную ошибку, он будет fail переход маршрута. Маршрутизатор в основном рухнет. Пользователь в основном просто увидит пустую страницу, потому что распознаватели не имеют никакой обработки ошибок.

Вышеприведенное только отлавливает ошибки HTTP, потому что это единственный вид, который, по нашему мнению, должен быть выдан. Другой вид ошибки следует рассматривать как ошибку.

Если компонент вызывает эту службу, то программист должен проверить флаг success для true до , доверяя выданному значению. Это может быть отфильтровано, если бизнес-логике все равно, если она выйдет из строя, или компонент может визуально показать пользователю, что ему не удалось выполнить HTTP-запрос. В любом случае ответ об ошибке HTTP не переходит к перехватчику ошибок приложения.

Это всего лишь подход . Люди делают свои вещи HTTP по-разному. Другой ответ правильно отвечает на ваш вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...