angular2 - 在 observable 完成后导航

angular2 - Navigate after observable is complete

我有一个像这样的 http observable,在我的 UserService:

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

显然,这可能会异步发生,我可能会在注销前结束导航。

使用 promises,我可以做这样的事情:

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

我怎样才能对可观察对象做同样的事情?在我的 UserService class 中,我想创建一个可观察对象,订阅它,在成功或出错时做一些事情,然后从我的视图组件导航。

您实际上可以使 logout 方法 return 成为一个承诺并正常使用它。它不一定是可观察的:

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

您不能等待 Observable 结束,因为它的流可能会无限期地继续。但是您可以在 subscribe 方法中调用 router.navigate

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 returns 一个 Subscriptionunsubscribe 方法停止等待 Observable 的数据。因此,如果必须,您可以等待超时时间并调用 unsubscribe.

Observable对象终于有方法了,试试吧。 别忘了先导入:

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

    });
  }

如果你真的想使用 promise:

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

注销需要 return 一个 Observable 而不是 Subscription。 例如:

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

有关operators/methods的更多信息:https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md