【问题标题】:How to get typescript http.get observable to wait for parameter to be returned inline?如何让 typescript http.get observable 等待参数返回内联?
【发布时间】:2019-05-21 04:04:27
【问题描述】:

好的,所以我正在尝试调用 http.get 来等待返回参数之一 (getUserToken),然后再调用 http.get 函数。我不想在这里将它们链接在一起,因为我的调用函数 getSomeData 返回一个 observable,然后被许多其他函数调用。

getSomeData 是需要返回 getUserToken 但 getUserToken 始终为空的,因为我没有正确地做承诺。很抱歉,我在这里没有看到解决方案。

这个函数开始调用,有很多函数可以调用,我不想在这里改变任何东西。

displayData(){
 let mySubscription = this.getSomeData();
    mySubscription.subscribe(retJson => {
      if (retJson != null && retJson !== undefined){
        console.log(retJson);
      }
    });
}

这是返回 http.get 的调用,问题在 getUserToken 中。我需要 http.get 来等待 getUserToken()。

getSomeData(){
     let temporary = this.http.get(serviceUrl, getUserToken() ).map((response: Response) => {
       return response;
  });
return temporary;
}

问题是 getUserToken 自己调用服务器,有没有办法将它包装在一个 observable 或 Promise 中,可以在 getSomeData 调用中调用和解析 http.get 内联?

getUserToken(){
     this.authenticationService.getToken()
            .subscribe(responseData => {
              if (responseData){
                let headers = new Headers({ 'Authorization': 'Bearer ' + responseData.token });
                return new RequestOptions({ headers: headers });
              }
            });
}


【问题讨论】:

    标签: typescript promise observable httprequest angular2-observables


    【解决方案1】:

    您可以通过使用switchMap 来实现。

    @Injectable()
    class SomeClass {
       // Constructor omitted
    
       public displayData():void {
          const subscription:Subscription = this.getSomeData()
             .filter(retJson => !!retJson) // Only if json is truthy
             .subscribe(console.log);
       }
    
       // Get the user token, then switch to the actual data
       private getSomeData():Observable<any /*Replace with correct data type*/ > {
          return this.getUserToken() // get the user token
             .switchMap(userToken => // This is the token -> switchMap basically subscribes to the getUserToken and returns another observable
                this.http.get(serviceUrl, // switch to another observable as soon as getUserToken gives a value
                   new RequestOptions({headers: new Headers({...userToken})}) // optionally, add other headers here
                )
             );
       }
    
       private getUserToken():Observable<{authorization: string}> {
          return this.authenticationService.getToken()
            .filter(responseData => !!responseData) // only if responseData is truthy
            .map(responseData => ({'Authorization': `Bearer ${responseData.token}`})); // Map to the object representing the header header
       }
    
    }
    

    或者,为了让流更明显,你可以在一个方法中这样写(不推荐,只是为了让流更明显):

    const subscription:Subscription = this.authenticationService.getToken()
       .filter(responseData => !!responseData) // only if responseData is truthy
       .switchMap(userToken => // This is the token -> switchMap basically subscribes to the getUserToken and returns another observable
            this.http.get(serviceUrl, // switch to another observable as soon as getUserToken gives a value
               new RequestOptions({headers: new Headers({'Authorization': `Bearer ${responseData.token}`})}) // optionally, add other headers here
            )
        )
        .filter(retJson => !!retJson) // Only if json is truthy
        .subscribe(console.log);
    

    【讨论】:

    • 谢谢,这是一个可靠的答案,我不知道 switchMap。我会尽快尝试一下
    • 这对我有用,谢谢@pascalpuetz。我使用了 flatMap 以保证所有调用都完成,但您的解决方案很不错
    猜你喜欢
    • 1970-01-01
    • 2016-09-15
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 2019-07-24
    • 1970-01-01
    • 2021-07-26
    • 2013-07-22
    相关资源
    最近更新 更多