web-dev-qa-db-ja.com

angular2-observableが完了した後にナビゲートする

私のhttpには、そのような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']);
  }
_

明らかに、これは非同期に発生する可能性があり、ログアウトする前にナビゲートする可能性があります。

約束を使用すると、次のようなことができます。

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

オブザーバブルで同じことを行うにはどうすればよいですか?私のUserServiceクラスでは、オブザーバブルを作成し、サブスクライブし、成功またはエラーが発生したときに何かを行い、ビューコンポーネントからナビゲートします。

15
JMac

実際にlogoutメソッドにpromiseを返させ、通常どおり使用することができます。観察可能である必要はありません:

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

観測可能なオブジェクトには最後にメソッドがあります。試してください。最初にインポートすることを忘れないでください:

import 'rxjs/operators/finally';

Logout()は次のようになります。

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

ストリームが無期限に継続する可能性があるため、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']);
    });
  }

これが十分でない場合、subscribeSubscriptionを返し、そのunsubscribeメソッドはObservableのデータの待機を停止します。そのため、必要に応じて、タイムアウト期間を待ってunsubscribeを呼び出すことができます。

0
MatthewScarpino

ログアウトは、サブスクリプションではなく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

0
nakuzm