web-dev-qa-db-fra.com

Opérateur de finalisation RxJS non appelé

J'essaie de déclencher un rappel lorsque tous mes observables sont exécutés. Dans mon autre projet plus ancien, j'ai utilisé finally comme ça et cela a fonctionné comme un charme:

this.myService.callDummy()
  .finally(() => console.log('Works!'))
  .subscribe(result => ...)

Mais maintenant j'utilise une version plus récente de RxJS avec Opérateurs canalisables, mais l'appel finally (maintenant renommé finalize) n'est jamais exécuté. Il y a peu d'informations à trouver et je ne suis pas sûr de ce que je fais mal.

combineLatest(
  this.route.queryParams,
  this.myService.callDummy1(),
  this.myService.callDummy2()
)
.pipe(finalize(() => console.log('Does not work!')))
.subscribe(results => ...);

Toute aide est appréciée.

11
Nico Van Belle

Dans les observables, tirer et terminer ne sont pas la même chose.

Même si chacun des éléments émet une valeur, route.queryParams par définition ne se terminera jamais car c'est ainsi que Angular l'implémente, comme observable sans terminaison. Vous devrez le compléter manuellement pour votre finaliser pour s'exécuter car combineLatest ne se terminera que lorsque CHAQUE observable étant combiné à l'intérieur de celui-ci sera terminé.

combineLatest(
  this.route.queryParams.pipe(take(1)), // take(1) will complete the observable after it has emitted one value
  this.myService.callDummy1(),
  this.myService.callDummy2()
)
.pipe(finalize(() => console.log('Does not work!')))
.subscribe(results => ...);

cela se terminera.

9
bryan60

Êtes-vous sûr que l'un des Observables combinés se termine réellement? Soit .complete ou .error?

Si aucun des combinés Observable ne se termine, finally ne sera jamais appelé.

0
ritaj

Si vous voulez faire quelque chose lorsque l'observable se termine, utilisez le rappel complet au lieu de finalement/finaliser:

.subscribe(
    value => { console.log(`Next: ${value}`); },
    error => { console.log(`Error: ${error}`); },
    ()    => { console.log(`Completed`); }
);

Quoi qu'il en soit, finalement/finalize devrait également fonctionner et sera appelé en cas d'erreur OR complete. Im assez sûr que votre observable ne se termine jamais. Vous pouvez le confirmer en utilisant mon code ci-dessus.

Je vois que vous utilisez Angular et que vous vous abonnez à this.route.queryParams Qui ne se termine jamais. Vous pouvez créer un nouvel observable en utilisant first() pour obtenir la valeur et il termine immédiatement: this.route.queryParams.pipe(first())

0
Mick