Проблема с несколькими наблюдаемыми в Typescript - PullRequest
2 голосов
/ 18 июня 2019

У меня есть служба с именем API, и первое, что нужно сделать службе, это проверить, является ли токен API действительным, когда токен действителен, продолжить выполнение вызываемой функции. Проблема здесь заключается в том, что запрос нового токена и вызов API вызываются одновременно.

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

Функция checkToken

/*
This function has to run FIRST before the api call (below) is beigin executed.
The issue now is both functions are running at the same time, when the token is expired the call will fail. 
*/

checkToken(): Observable<any> {
    //this function will check the API token and either request a new token or do nothing.

    // Check if session is valid based on timestamp
    if (Number(currentTimestamp) + 5000 >= Number(userSession)) {
         // Session is valid, do nothing.
         return;
    } else {
         // Get new token and save in storage
         return;
    }
}

Пример вызова API (в моем сервисе несколько типов вызовов)

getValuations(): Observable<Valuation[]> {
     this.checkToken(); // This function has to run (and complete)  first before continue.

     //The issue now is that the function below is executing at the same time as 
     checkToken()  

     return this.http.get<Valuation[]>();
}

Здесь я использую данные.

 this.apiService.getValuations(this.Taxid).subscribe(res => {

 });

Я ожидаю, что функция checkToken запустится первой и продолжит работу с функцией getValuations. Но очевидно, что они выполняются одновременно, что приведет к выполнению вызова API с недействительным токеном.

Ответы [ 3 ]

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

Используйте оператор switchMap:

getValuations(): Observable<Valuation[]> { 
     return this.checkToken()
       .pipe(switchMap(token => this.http.get<Valuation[]>()));
}

Это будет

  • Проверьте токен
  • после получения ответа , сделать второй запрос
  • вернуть результат второго запроса
0 голосов
/ 18 июня 2019

Вы должны обновить свой код следующим образом:

checkToken(): Observable<any> {

        //this function will check the API token and either request a new token or do nothing.

        // Check if session is valid based on timestamp
        if (Number(currentTimestamp) + 5000 >= Number(userSession)) {
            // Session is valid, do nothing.
            //and let the observable pipe line handle it
            return of(true);
        } else {
            // Get new token and save in storage
            //session is not valid then first get the token and save ithe new token in the storage
            //adjust this code to have API which gets the new token
            return this.apiMethodWhichGetsTheNewToken()
                            .pipe(
                                map(newToken => {
                                    //save the token in the storage....

                                    return true;
                                })
                            )
        }
    }

А теперь используйте метод checkToken (), который возвращает наблюдаемое, как это:

getValuations(): Observable<Valuation[]> { 
     return this.checkToken()
       .pipe(switchMap(token => this.http.get<Valuation[]>()));
}
0 голосов
/ 18 июня 2019

Вам просто нужно передать ответ о создании или проверке нового токена.Что-то в этих строках.

//this is returning an observable, simply pipe its response.
checkToken(): Observable<any> {
//this function will check the API token and either request a new token or do nothing.
}



getValuations(): Observable<Valuation[]> {
  //this is going to call checkToken() first, when that is complete
  // this.http.get() request will be called.
  return this.checkToken().pipe(
    mergeMap(_ =>  this.http.get<Valuation[]>())
  );
}
...