打字稿中有多个可观察物的问题

时间:2019-06-18 09:28:27

标签: angular typescript rxjs observable

我有一个名为API的服务,该服务要做的第一件事是检查API令牌是否有效,当令牌有效时,继续执行被调用的函数。这里的问题是,同时调用新令牌和API调用。

我尝试将checkToken函数更改为await,并将最终的API调用更改为async,但这不起作用,因为该函数是可观察的。

功能checkToken

myexpr <- expr((Temp - 32) / 1.8)
eval_tidy(myexpr, data = as_data_mask(list(), parent = e)) # still fails since parent is overridden 
eval_tidy(myexpr, data = list(), env = e) # works since there's no quosure env to override env

API调用示例(我的服务中有多种调用类型)

/*
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;
    }
}

这里我正在使用数据。

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[]>();
}

我希望checkToken函数首先运行,然后继续执行getValuations函数。但是很明显,它们是同时执行的,这将导致使用无效令牌执行API调用。

3 个答案:

答案 0 :(得分:2)

使用switchMap运算符:

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

这将

  • 检查令牌
  • 一旦收到回复,则发出第二个请求
  • 返回第二个请求的结果

答案 1 :(得分:0)

您只需要通过管道传递新令牌创建或检查的响应。这些线上的东西。

//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[]>())
  );
}

答案 2 :(得分:0)

您应该像这样更新代码:

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[]>()));
}