Me gustaría poder esperar en un observable, p. Ej.
const source = Rx.Observable.create(/* ... */)
//...
await source;
Un intento ingenuo da como resultado que la espera se resuelva de inmediato y no bloquee la ejecución.
Editar: El pseudocódigo para mi caso de uso previsto completo es:
if (condition) {
await observable;
}
// a bunch of other code
Entiendo que puedo mover el otro código a otra función separada y pasarlo a la devolución de llamada de suscripción, pero espero poder evitarlo.
javascript
rxjs
ecmascript-7
CheapSteaks
fuente
fuente
.subscribe()
llamada de método?Respuestas:
Tienes que pasarle una promesa
await
. Convierta el próximo evento del observable en una promesa y espere eso.Nota de edición: esta respuesta originalmente usaba .take (1) pero se cambió para usar .first (), lo que evita que el problema de la Promesa nunca se resuelva si la transmisión termina antes de que llegue un valor.
fuente
await observable.first().toPromise();
?first()
resultará en rechazo ytake(1)
resultará en promesa pendiente.take(1)
nifirst()
en casos como este. Como está esperando que ocurra exactamente UN evento, debe usar elsingle()
cual lanzará una excepción si hay más de 1, mientras que no lanzará una excepción cuando no hay ninguna. Si hay más de uno, es probable que haya algún error en su código / modelo de datos, etc. Si no usa single, terminará eligiendo arbitrariamente el primer artículo que regresa sin advertir que hay más. Debería tener cuidado en su predicado sobre la fuente de datos ascendente para mantener siempre el mismo orden.import 'rxjs/add/operator/first';
Probablemente tenga que ser
Como se señaló anteriormente en los comentarios, existe una diferencia sustancial entre los operadores
take(1)
yfirst()
cuando hay un observable completo vacío.Observable.empty().first().toPromise()
dará como resultado un rechazoEmptyError
que se puede manejar en consecuencia, porque realmente no había ningún valor.Y
Observable.empty().take(1).toPromise()
resultará en una resolución conundefined
valor.fuente
take(1)
rendirá una promesa pendiente. Rendirá una promesa resuelta con .undefined
Necesitará
await
una promesa, por lo que querrá usartoPromise()
. Consulte esto para obtener más detalles sobretoPromise()
.fuente
Si
toPromise
está desaprobado para usted, puede usarlo,.pipe(take(1)).toPromise
pero como puede ver aquí , no está desaprobado.Así que por favor use
toPromise
(RxJs 6) como se dijo:ejemplo async / await:
Leer más aquí .
Y elimine esta afirmación incorrecta que dice que
toPromise
está obsoleta.fuente