Как фильтр Rxjs откладывает http-вызовы, пока критерии не соответствуют приведенному ниже коду? - PullRequest
0 голосов
/ 20 сентября 2019

У меня есть блок кода, который возвращает функцию next углового перехватчика, если значение субъекта поведения tokenSubject не равно нулю.

if (!this.tokenRefreshing) {
  this.tokenRefreshing = true;
  this.tokenSubject.next(null);
  return this.loginService.getNewRefreshToken().pipe(
    switchMap((tokenResponse: any) => {
      if (tokenResponse) {
        localStorage.setItem('jwtToken', tokenResponse.jwtToken);
        localStorage.setItem('refreshToken', tokenResponse.refreshToken.value)
        localStorage.setItem('UserName', tokenResponse.userName);
        this.tokenSubject.next(tokenResponse);
        console.log('token refreshed');
        return next.handle(this.attachAuthToken(request));
      }
      else return <any>this.loginService.userLogout();
    }),
    catchError(err => {
      this.loginService.userLogout();
      return this.handleError(err);
    }),
    finalize(() => {
      this.tokenRefreshing = false;
    })
  )
}
else {
  return this.tokenSubject.pipe(
    filter(token => token != null),
    take(1),
    switchMap(token => {
      return next.handle(this.attachAuthToken(request))
    }),
    catchError((error) => {
      this.tokenRefreshing = false;
      return this.loginService.userLogout();
    })
  )
}

Я не могу понять, как это работает, если несколько httpназывает попадания туда и как он откладывает и выполняет все по порядку после того, как у субъекта поведения есть значение токена.Может ли кто-нибудь помочь мне понять это?

Ответы [ 2 ]

1 голос
/ 20 сентября 2019

Прежде всего просто проясните, что это логика обработки ошибок в методе this.handle401Error (https://angular -academy.com / angular-jwt / )

, если вывыполнение этого означает, что ваш токен признан недействительным, и вам необходимо получить токен обновления.Допустим, у вас есть 5 https-вызовов, попавших в этот блок, когда токен больше не действителенПервый HTTP-вызов попадает в него, он меняет

this.tokenRefreshing = true;

и немедленно выдает tokenSubject как ноль на

  this.tokenSubject.next(null);

, затем запрашивает новый токен и, как только он получает, устанавливает токен взаголовок и переход, чтобы пропустить исходный запрос через

next.handle(this.attachAuthToken(request));

, так завершается первый http.

Но теперь у вас есть еще один http-удар, когда вы обновляете токен (1-й http при запуске и запросе обновления токена).

этот 2-й http-вызов будет запускать else блок, потому что this.tokenRefreshing true, поэтому в tokenSubject он смотрит, есть ли какое-либо значение, а в данный момент его нет.таким образом, вызов будет просто зависать / приостанавливаться там, но не будет отменен, так как вы отфильтровываете token===null

filter(token => token != null),

, поэтому, когда 1-й http завершает получение refreshtoken, он делает это

this.tokenSubject.next(tokenResponse);

, который вызовет второй http-вызов для возобновления последующих элементов потока

   take(1),
    switchMap(token => {
      return next.handle(this.attachAuthToken(request))
    }),
    catchError((error) => {
      this.tokenRefreshing = false;
      return this.loginService.userLogout();
    })

Надеюсь, это поможет.

1 голос
/ 20 сентября 2019

Как вы уже сказали, у вас есть перехватчик.Перехватчики в целом выполнены по порядку.Метод перехвата возвратил наблюдаемое (Observable<HttpEvent<any>>).Теперь вы возвращаете асинхронный субъект, сопоставленный каналу, с этой наблюдаемой, которая завершается после того, как вы получили токен.Angular ждет этого завершения.

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