web-dev-qa-db-fra.com

Comment faire la séquence en chaîne dans rxjs

Je voudrais quelque chose comme:

this._myService.doSomething().subscribe(result => {
  doSomething()
});
.then( () => dosthelse() )
.then( () => dosanotherthing() )

Je voudrais donc enchaîner. Alors comme promis. Comment ferais-je cela dans Rxjs?

this._myService.getLoginScreen().subscribe( result => {
      window.location.href = MyService.LOGIN_URL;
      /// I would like to wait for the site to load and alert something from       the url, when I do it here it alerts the old one
    });
   .then (alert(anotherService.partOfTheUrl())


getLoginScreen() {
  return this.http.get(myService.LOGIN_URL)
.flatMap(result => this.changeBrowserUrl())
.subscribe( result => //i want to do sth when the page is loaded//);
}

changeBrowserUrl(): Observable<any> {
return Observable.create( observer => {
window.location.href = myService.LOGIN_URL;
observer.next();
});
}
36
adam nowak

L'équivalent de then pour les éléments observables serait flatMap. Vous pouvez voir quelques exemples d'utilisation ici:

Pour votre exemple, vous pourriez faire quelque chose comme:

this._myService.doSomething()
  .flatMap(function(x){return functionReturningObservableOrPromise(x)})
  .flatMap(...ad infinitum)
  .subscribe(...final processing)

Faites attention aux types de ce que vos fonctions retournent, pour enchaîner des observables avec flatMap vous aurez besoin de retourner une promesse ou une observable.

59
user3743222

Si dosthelse ou dosanotherthing renvoie une valeur brute, l'opérateur à utiliser est map. S'il s'agit d'une observable, l'opérateur est flatMap (ou équivalent).

Si vous voulez faire quelque chose impérativement. Je veux dire en dehors de la chaîne de traitement asynchrone, vous pouvez tirer parti de l’opérateur do.

En supposant que dosthelse renvoie un observable et dosanotherthing un objet brut, votre code serait:

this._myService.doSomething()
  .do(result => {
    doSomething();
  })
  .flatMap( () => dosthelse() )
  .map( () => dosanotherthing() );

Notez que si vous retournez le résultat de la méthode subcribe, cela correspondra à un objet subscription et non à un observable. Un objet d'abonnement sert principalement à pouvoir annuler l'observable et ne peut pas faire partie de la chaîne de traitement asynchrone.

En fait, la plupart du temps, vous vous abonnez au bout de la chaîne.

Donc, je refactoriser votre code de cette façon:

this._myService.getLoginScreen().subscribe( result => {
  window.location.href = MyService.LOGIN_URL;
  /// I would like to wait for the site to load and alert something from       the url, when I do it here it alerts the old one
  alert(anotherService.partOfTheUrl()
});

getLoginScreen() {
  return this.http.get(myService.LOGIN_URL)
    .flatMap(result => this.changeBrowserUrl())
    .do( result => //i want to do sth when the page is loaded//);
}

changeBrowserUrl(): Observable<any> {
  return Observable.create( observer => {
    window.location.href = myService.LOGIN_URL;
    observer.next();
  });
}
11
Thierry Templier