2016-02-11 53 views
12

我有一個http觀察到像這樣,在我UserServiceangular2 - 導航後可觀察到的是完整的

logout() { 
    return this.http.delete(this.baseUrl + url, { 
      headers: this.headers() 
     }).map((res: IResponse) => { 
      var json = res.json(); 
      json.headers = res.headers; 
      return json; 
     }).subscribe((response) => { 
      //DO SOMETHING, THEN ---- 
      return res; 
     }); 
} 

我已經創建了一個可觀察到的,並創建了一個訂閱(response),這是成功的返回值。現在

,在我的部分,我想打電話給UserService.logout()然後導航到一個新的路線:

logout() { 
    this.userService.logout(); 
    this.router.navigate(['LandingPage']); 
    } 

很明顯,這可能是異步的,我可能最終我的導航在註銷之前。

使用的承諾,我可以做這樣的事情:

this.userService.logout().then(() => { this.router.navigate(['LandingPage']); });

我怎樣才能做到與觀測同樣的事情?在我的UserService類中,我想創建一個observable,訂閱它,在成功或錯誤時做一些事情,然後從我的view組件導航。

回答

14

你實際上可以讓logout方法返回一個承諾,並像平常一樣使用它。它沒有可觀察到:

logout() { 
    return new Promise((resolve, reject) => { 
     this.http.delete(this.baseUrl + url, { headers: this.headers() }) 
      .map((res: IResponse) => { 
       var json = res.json(); 
       json.headers = res.headers; 
       return json; 
      }) 
      .subscribe(data => { 
       //DO SOMETHING, THEN ---- 
       resolve(data); 
      }, error => reject(error)); 
    }); 
} 

logout() { 
    this.userService.logout().then(response => this.router.navigate(['LandingPage'])) 
} 
+1

非常有用的例子。謝謝:-) – brinch

0

你不能等待Observable來完成,因爲它的流可能會繼續下去。但是,你可以調用router.navigatesubscribe方法中:

logout() { 
    return this.http.delete(this.baseUrl + url, { headers: this.headers() }) 
    .map((res: IResponse) => res.json()) 
    .subscribe((response) => { 
     //DO SOMETHING, THEN ---- 
     this.router.navigate(['LandingPage']); 
    }); 
    } 

如果這還不夠,subscribe返回Subscriptionunsubscribe方法停止等待Observable的數據。所以如果你需要,你可以等待一個超時時間,然後撥打unsubscribe

5

最終觀察對象有方法,試試吧。 不要忘了先導入:

import 'rxjs/operators/finally'; 

你退出()將是:

logout() { 
    return this.http.delete(this.baseUrl + url, { headers: this.headers() }) 
    .map(res => res.json()) 
    .finally(() => this.router.navigate(['LandingPage'])) 
    .subscribe((response) => { 
     //DO SOMETHING, THEN ---- 

    }); 
    } 

如果你真的想用承諾:

import 'rxjs/add/operator/toPromise'; 

logout() { 
    return this.http.delete(this.baseUrl + url, { headers: this.headers() }) 
    .map(res => res.json()); 

在component.ts

var aPromise = this.userService.logout().toPromise(); 
aPromise.then(() => { 
    this.router.navigate(['LandingPage']); 
}); 
+0

你救我的一天男人!花了我5個小時,終於解決了我的問題 – gsiradze

+0

真棒!只要回報社區。很高興能有一些幫助。 – codely

+2

'finally()'很好,但你必須正確導入它:'import'rxjs/add/operator/finally';' – gkri

0

註銷需要r修改Observable而不是訂閱。 例如:

logout(): Observable<T> { 
 
     return this.http.delete(this.baseUrl + url, { 
 
       headers: this.headers() 
 
      }).map((res: IResponse) => { 
 
       var json = res.json(); 
 
       json.headers = res.headers; 
 
       return json; 
 
      }) 
 
      .catch((err)=>Observable.empty()) // return empty if error 
 
      .share(); // to ensure that no duplicate http calls can occur 
 
    
 
    } 
 

 
    //in component: 
 

 
    this.service.logout() 
 
     .do(()=>this.router.navigate(['LandingPage']);)//do stuff 
 
     .subscribe((res:any)=>{}); 
 

 
    //or with template async pipe: 
 

 
    public result$ = Observable<T>; 
 

 
    result$ = this.service.logout() 
 
     .do(()=>//do stuff); 
 

 
    //in template: 
 
    
 
    {{(result$ | async)?.id}} 
 
    or simply 
 
    {{result$ | async}} 
 

 
    // P.s. do not forget about unsubscribe(), thats why I prefer to use async (since that's the Async pipe's job.)

有關經營者/方法的更多信息:https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md