J'aimerais pouvoir attendre sur un observable, par exemple
const source = Rx.Observable.create(/* ... */)
//...
await source;
Une tentative naïve entraîne la résolution immédiate de l'attente et non le blocage de l'exécution
Edit: Le pseudocode pour mon cas d'utilisation prévu complet est:
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 passer dans le rappel d'abonnement, mais j'espère pouvoir éviter cela.
javascript
rxjs
ecmascript-7
Steaks bon marché
la source
la source
.subscribe()
appel de méthode?Réponses:
Vous devez faire une promesse
await
. Convertissez le prochain événement de l'observable en promesse et attendez cela.Modifier la note: Cette réponse utilisait à l'origine .take (1) mais a été modifiée pour utiliser .first (), ce qui évite que la promesse ne se résolve jamais si le flux se termine avant qu'une valeur ne passe.
la source
await observable.first().toPromise();
?first()
entraînera le rejet ettake(1)
entraînera une promesse en attente.take(1)
nifirst()
dans des cas comme celui-ci. Puisque vous vous attendez à ce qu'exactement UN événement se produise, vous devez utilisersingle()
qui lèvera une exception s'il y en a plus de 1, sans lever d'exception lorsqu'il n'y en a pas. S'il y en a plus d'un, il y a probablement quelque chose qui ne va pas dans votre code / modèle de données, etc. Si vous n'utilisez pas de single, vous finirez par choisir arbitrairement le premier élément qui retourne sans vous avertir qu'il y en a plus. Vous devrez faire attention dans votre prédicat sur la source de données en amont pour toujours maintenir le même ordre.import 'rxjs/add/operator/first';
Cela doit probablement être
Comme il a été noté dans les commentaires précédents, il existe une différence substantielle entre les opérateurs
take(1)
etfirst()
lorsqu'il y a un observable rempli vide.Observable.empty().first().toPromise()
entraînera un rejet avecEmptyError
qui peut être géré en conséquence, car il n'y avait vraiment aucune valeur.Et
Observable.empty().take(1).toPromise()
se traduira par une résolution avec de laundefined
valeur.la source
take(1)
, ne donnera pas une promesse en suspens. Cela donnera une promesse résolue avecundefined
.Vous aurez besoin d'
await
une promesse, vous voudrez donc l'utilisertoPromise()
. Voir ceci pour plus de détails surtoPromise()
.la source
Si
toPromise
est obsolète pour vous, vous pouvez l'utiliser,.pipe(take(1)).toPromise
mais comme vous pouvez le voir ici, il n'est pas obsolète.Alors s'il vous plaît utilisez juste
toPromise
(RxJs 6) comme dit:exemple async / await:
En savoir plus ici .
Et veuillez supprimer cette fausse revendication disant qu'elle
toPromise
est obsolète.la source