2016-02-11 25 views
12

Tôi có một http thể quan sát được như vậy, trong UserService tôi:angular2 - Navigate sau khi quan sát được hoàn tất

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; 
     }); 
} 

Tôi đã tạo ra một thể quan sát được, và tạo ra một thuê bao (response) mà là giá trị thành công trở lại.

Bây giờ, trong thành phần của tôi, tôi muốn gọi UserService.logout() và sau đó điều hướng đến một con đường mới:

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

Rõ ràng, điều này có thể xảy ra không đồng bộ và tôi có thể kết thúc điều hướng trước khi tôi đăng xuất.

Sử dụng những lời hứa, tôi có thể làm một cái gì đó như thế này:

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

Làm thế nào tôi có thể làm điều tương tự với quan sát? Trong lớp UserService của tôi, tôi muốn tạo ra một quan sát, đăng ký với nó, làm một số thứ về thành công hoặc lỗi, THEN điều hướng từ thành phần khung nhìn của tôi.

Trả lời

14

Bạn thực sự có thể thực hiện phương thức logout trả lại lời hứa và sử dụng nó như bình thường. Nó không phải là Quan sát:

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

dụ Rất hữu ích. Cảm ơn :-) – brinch

0

Bạn không thể đợi Observable để kết thúc vì luồng của nó có thể tiếp tục vô thời hạn. Nhưng bạn có thể gọi router.navigate bên trong phương pháp subscribe:

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

Nếu đây là không đủ, subscribe trả về một phương pháp Subscriptionunsubscribe dừng chờ đợi dữ liệu 's Observable. Vì vậy, nếu bạn phải, bạn có thể chờ một khoảng thời gian chờ và gọi unsubscribe.

5

Đối tượng quan sát có phương pháp cuối cùng, hãy thử. Đừng quên để nhập khẩu đầu tiên:

import 'rxjs/operators/finally'; 

logout của bạn() sẽ là:

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 ---- 

    }); 
    } 

Nếu bạn thực sự muốn sử dụng lời hứa:

import 'rxjs/add/operator/toPromise'; 

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

trong component.ts

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

bạn tiết kiệm người đàn ông ngày của tôi !!! phải mất 5 giờ của tôi và cuối cùng đã giải quyết được vấn đề của tôi – gsiradze

+0

tuyệt vời! Chỉ cần trả ơn cho cộng đồng. Vui mừng được giúp đỡ một số. – codely

+2

'finally()' hoạt động tốt, nhưng bạn phải nhập nó một cách chính xác: 'import 'rxjs/add/operator/finally';' – gkri

0

Đăng xuất cần r eturn một Observable không phải là một Subscription. Ví dụ:

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.)

Để biết thêm thông tin về các nhà khai thác/phương pháp: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md

Các vấn đề liên quan