Я пытаюсь заставить эти наблюдаемые RXJS правильно работать с Angular 7, но я не могу понять, что не так.
Что я хочу сделать, это проверить, есть ли состояние проверки токена каждые 10 секунд дляauth.
import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {interval, Observable, of, timer} from 'rxjs';
import {concatMap, delay, flatMap, takeWhile, tap} from 'rxjs/operators';
import {Token} from './Token';
import {User} from './User';
import {TokenFactory} from './factory/tokenfactory';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
@Injectable({
providedIn: 'root'
})
export class TokenService {
private user;
private token;
private tokenLoginUrl = 'http://localhost:8080/login_check';
private refreshTokenUrl = 'http://localhost:8080/token/refresh';
constructor(private http: HttpClient) { }
private verifyTokenState(): Observable<any> {
if (!localStorage.getItem('token')) {
this.getLoginInfo().subscribe(token => {
this.token = TokenFactory.createToken(token.token, token.refresh_token, Date.now(), true);
return of(this.token);
});
this.token = {};
return of(this.token);
}
this.token = TokenFactory.getTokenFromLocalStorage();
const timeElapsedInMinutes = (Date.now() - this.token.date_token) / 1000 / 60;
console.log(timeElapsedInMinutes);
if (timeElapsedInMinutes >= 59) {
this.getRefreshToken(this.token).subscribe(jsonToken => {
this.token = TokenFactory.createToken(jsonToken.token, jsonToken.refresh_token, Date.now(), true);
return of(this.token);
});
}
return of(this.token);
}
private getLoginInfo(): Observable<any> {
return this.http.post<Token>(this.tokenLoginUrl, this.user, httpOptions);
}
private getRefreshToken(token: Token): Observable<any> {
return this.http.post<Token>(this.refreshTokenUrl, token, httpOptions);
}
public getToken() {
return timer(0, 10000).pipe(
flatMap(() => this.verifyTokenState()),
takeWhile(() => this.token !== undefined && !this.token.isValid)
);
}
public setUser(user: User): void {
this.user = user;
}
}
У меня проблема в том, что когда я вызываю get TokenService.getToken () из другого компонента (скажем, в компоненте входа в систему после того, как пользователь нажимает кнопку отправки), и я использую timer(0,10000)
Методы getLoginInfo () и getRefreshToken () вызываются в бесконечном цикле, и запускаются сотни вызовов ajax.
public getToken() {
return timer(0, 10000).pipe(
flatMap(() => this.verifyTokenState()),
takeWhile(() => this.token !== undefined && !this.token.isValid)
);
}
Я не понимаю, что если я использую 2000 вместо0 в качестве первого параметра, все работает нормально, но это не то, что я хочу.
public getToken() {
return timer(2000, 10000).pipe(
flatMap(() => this.verifyTokenState()),
takeWhile(() => this.token !== undefined && !this.token.isValid)
);
}
То, что я хочу, это чтобы наблюдаемый имел интервалы 10 секунд между вызовами, но я хочу, чтобы он начался немедленно.Я также хочу получить наблюдаемый токен, возвращаемый из getToken () после его возвращения из метода verifyTokenSate ().Так что именно не так?Есть ли лучший способ сделать это?Я хочу сделать это реактивным способом без отписки.
Проблемы, похоже, возникают в AuthInterceptor после дальнейшей проверки.Когда я удаляю из поставщиков модулей, все в порядке.Вот AuthInterceptor:
import {Injectable} from '@angular/core';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {TokenService} from './token.service';
import {Observable} from 'rxjs';
import {map, mergeMap} from 'rxjs/operators';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
private token;
constructor(private auth: TokenService) { }
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
let request = req.clone();
this.auth.getToken().subscribe(t => {
console.log(t);
if (t.token) {
console.log('token valid');
request = req.clone({
setHeaders: { Authorization: `Bearer ${t.token}` }
});
}
});
return next.handle(request);
}
}
Так что же не так внутри AuthInterceptor?