web-dev-qa-db-fra.com

Comment puis-je attendre sur un observable Rx?

Je voudrais pouvoir attendre sur un observable, par exemple.

const source = Rx.Observable.create(/* ... */)
//...
await source;

Une tentative naïve entraîne l'attente immédiate de la résolution et ne bloque pas l'exécution

Edit: le pseudocode pour mon cas d'utilisation complet est le suivant:

if (condition) {
  await observable;
}
// a bunch of other code

Je comprends que je peux déplacer l'autre code dans une autre fonction distincte et le transférer dans le rappel d'abonnement, mais j'espère pouvoir l'éviter.

76
CheapSteaks

Vous devez passer une promesse à await. Convertissez le prochain événement de l'observable en promesse et attendez cela.

if (condition) {
  await observable.first().toPromise();
}

Note de modification: cette réponse utilisait initialement .take (1) mais a été modifiée pour utiliser .first (), ce qui évite le problème de la promesse qui ne se résoudra jamais si le flux se termine avant qu'une valeur ne soit transmise.

95
Macil

Il doit être

await observable.first().toPromise();

Comme indiqué dans les commentaires précédents, il existe une différence substantielle entre les opérateurs take(1) et first() lorsqu'il y a une observable terminée vide.

Observable.empty().first().toPromise() entraînera un rejet avec EmptyError qui peut être traité en conséquence, ce qui est généralement un comportement souhaitable.

Et Observable.empty().take(1).toPromise() donnera lieu à une promesse en attente, ce qui est souhaitable ... presque jamais.

23
Estus Flask

Vous aurez besoin de await une promesse, vous voudrez donc utiliser toPromise(). Voir this pour plus de détails sur toPromise().

8
Josh Durham