Выполнять сервисную функцию в фоновом режиме каждые 4 минуты в angular 6

Я пытаюсь выполнить служебную функцию в фоновом режиме, которая получает токен обновления с сервера каждые 4 минуты.

 @Injectable()
 export class RefreshTokenService {
 time: any;
 token: string;
 email: string;
 credentials: any;

 constructor(private http: HttpClient) {
 }


  getToken(): string {
   const credentials = localStorage.getItem('credentials');
   if (credentials) {
     const parsedCredentials = JSON.parse(credentials);
     const token = parsedCredentials.token;
     return token;
   }
   return null;
  }

 refreshToken(token: string) {
   const tokenJson: any = {'token': token};
   this.http.post('/api-token-refresh/', tokenJson,   httpOptions).subscribe(response => {
     const data = JSON.parse(JSON.stringify(response));
     this.credentials = JSON.parse(localStorage.getItem('credentials'));
     this.credentials.token = data.token;
     localStorage.setItem('credentials',  JSON.stringify(this.credentials));
   });
 }}

Теперь я выполняю refreshToken() в the app.component.ts внутри ngOnInit(), поэтому он выполняется каждый раз, когда я загружаю страницу в приложение, и работает, как и ожидалось, но я не нашел правильного способа вызывать refreshToken() каждые 4 минуты в фоновом режиме. .

я уже смотрел на это, но, похоже, это не работает... Как вызывать функцию каждые 2 минуты в angular2?


person med.b    schedule 19.01.2019    source источник


Ответы (3)


Лучше всего использовать операторы interval и switchMap.

Сначала верните наблюдаемое из функции refreshToken. Используйте оператор карты, чтобы делать все остальные вещи, такие как преобразование данных, сохранение в локальном хранилище и т. д. в методе refreshToken().


import { interval, pipe } from 'rxjs'; 
import { map, switchMap } from 'rxjs/operators';

.....

refreshToken(token: string) {
   const tokenJson: any = {'token': token};
   return this.http.post('/api-token-refresh/', tokenJson,   httpOptions);
};

checkingTokenOnInterval(){
     const intervalTime = 4*60*1000;
     const token = 'sdfsdf';
     interval(intervalTime).pipe(switchMap(() => this.refreshToken(token))).subscribe(()=>{
                 //do something 
     });
}

Используйте checkingTokenOnInterval() для вызова вызова refreshToken каждые 4 минуты.

person Vikash Dahiya    schedule 19.01.2019
comment
Должен ли я вызывать checkingTokenOnInterval() внутри ngOnInit() в app.component.ts? - person med.b; 19.01.2019
comment
да, если вы хотите вызывать refreshToken каждые 4 минуты - person Vikash Dahiya; 19.01.2019
comment
Он действительно выполняется после периода, установленного в intervalTime, но выполняется только один раз, и после этого я выдаю эту ошибку ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. есть идея, как это исправить? - person med.b; 19.01.2019
comment
Я не уверен насчет этой ошибки, возможно, в коде rxjs будет небольшая синтаксическая ошибка, но вы можете проверить это stackblitz-demo - person Vikash Dahiya; 19.01.2019

Вы можете добиться этого с помощью RxJS/timer https://rxjs-dev.firebaseapp.com/api/index/function/timer

    this.refreshTokenService.refreshToken()
        .pipe
            tap(() => {
                // every 4 minutes refresh the discovery service
                const interval = 4 * 60 * 1000;
                timer(interval, interval).subscribe(() => {
                    this.refresh().subscribe();
                });
            })
        )
        .toPromise();
person shiva krishna    schedule 19.01.2019

Помните о запросах, которые отправляются сразу после запроса токена обновления со старым действительным токеном. Я рекомендую использовать перехватчик и ставить в очередь все запросы, отправленные после refreshToken. Подождите, пока придет refreshToken, а затем отправьте запросы в очередь.

Другой способ - поймать 401 Error -> запрос на копирование -> RefreshToken -> отправить копию запроса.

person Dmitriy Kavraiskyi    schedule 19.01.2019