Eu gostaria de ser capaz de esperar em um observável, por exemplo
const source = Rx.Observable.create(/* ... */)
//...
await source;
Uma tentativa ingênua resulta em esperar resolvendo imediatamente e não bloqueando a execução
Editar: o pseudocódigo para meu caso de uso pretendido completo é:
if (condition) {
await observable;
}
// a bunch of other code
Eu entendo que posso mover o outro código para outra função separada e passá-lo para o retorno de chamada de inscrição, mas espero ser capaz de evitar isso.
javascript
rxjs
ecmascript-7
Bifes baratos
fonte
fonte
.subscribe()
chamada de método?Respostas:
Você tem que passar uma promessa
await
. Converta o próximo evento do observável em uma promessa e espere por isso.Editar nota: esta resposta originalmente usava .take (1), mas foi alterada para usar .first (), o que evita o problema de a promessa nunca ser resolvida se o fluxo termina antes de um valor chegar.
fonte
await observable.first().toPromise();
?first()
isso resultará em rejeição etake(1)
em promessa pendente.take(1)
nemfirst()
em casos como este. Como você está esperando que exatamente UM evento aconteça, você deve usar osingle()
que lançará uma exceção se houver mais de 1, enquanto não lançará uma exceção quando não houver nenhuma. Se houver mais de um, provavelmente há algo errado em seu código / modelo de dados etc. Se você não usar o único, acabará escolhendo arbitrariamente o primeiro item que retorna sem avisar que há mais. Você teria que tomar cuidado com seu predicado na fonte de dados upstream para manter sempre a mesma ordem.import 'rxjs/add/operator/first';
Provavelmente tem que ser
Como foi observado nos comentários anteriores, há uma diferença substancial entre os operadores
take(1)
efirst()
quando há um vazio preenchido observável.Observable.empty().first().toPromise()
resultará em rejeição comEmptyError
isso pode ser tratado em conformidade, porque realmente não havia valor.E
Observable.empty().take(1).toPromise()
resultará em resolução comundefined
valor.fonte
take(1)
, não renderá uma promessa pendente. Isso renderá uma promessa resolvida comundefined
.Você vai precisar de
await
uma promessa, então você vai querer usartoPromise()
. Veja isto para mais detalhes emtoPromise()
.fonte
Se
toPromise
estiver obsoleto para você, você pode usar,.pipe(take(1)).toPromise
mas como pode ver aqui , não está obsoleto.Então, por favor, use
toPromise
(RxJs 6) como disse:exemplo async / await:
Leia mais aqui .
E remova esta afirmação errada que diz que
toPromise
está obsoleta.fonte