Я бы хотел дождаться наблюдаемого, например
const source = Rx.Observable.create(/* ... */)
//...
await source;
Наивная попытка приводит к немедленному разрешению ожидания и не блокирует выполнение
Изменить: псевдокод для моего полного предполагаемого варианта использования:
if (condition) {
await observable;
}
// a bunch of other code
Я понимаю, что могу переместить другой код в другую отдельную функцию и передать его в обратный вызов подписки, но я надеюсь, что смогу этого избежать.
javascript
rxjs
ecmascript-7
CheapSteaks
источник
источник
.subscribe()
вызов метода?Ответы:
Вы должны передать обещание
await
. Преобразуйте следующее событие наблюдаемого в обещание и дождитесь этого.Примечание для редактирования: в этом ответе изначально использовался .take (1), но он был изменен на использование .first (), что позволяет избежать проблемы, связанной с тем, что Promise никогда не разрешается, если поток заканчивается до того, как будет получено значение.
источник
await observable.first().toPromise();
?first()
приведет к отклонению иtake(1)
приведет к отложенному обещанию.take(1)
ни другоеfirst()
в подобных случаях. Поскольку вы ожидаете, что произойдет ровно ОДНО событие, вы должны использовать его,single()
который вызовет исключение, если их больше 1, но не выбрасывает исключение, если его нет. Если их несколько, вероятно, что-то не так в вашем коде / модели данных и т. Д. Если вы не используете single, вы в конечном итоге произвольно выберете первый элемент, который возвращается без предупреждения о том, что их больше. Вам нужно будет позаботиться о своем предикате в вышестоящем источнике данных, чтобы всегда поддерживать один и тот же порядок.import 'rxjs/add/operator/first';
Вероятно, это должно быть
Как было отмечено в комментариях прежде, есть существенная разница между
take(1)
иfirst()
операторами , когда пусто завершен наблюдаемым.Observable.empty().first().toPromise()
приведет к отклонению сEmptyError
этим можно обработать соответствующим образом, потому что действительно не было никакой ценности.И
Observable.empty().take(1).toPromise()
приведет к разрешению соundefined
значением.источник
take(1)
будет не давать отложенное обещание. Это даст обещание, разрешенное с помощьюundefined
.Вам понадобится
await
обещание, поэтому вы захотите его использоватьtoPromise()
. См. Это для более подробной информацииtoPromise()
.источник
Если
toPromise
осуждается для вас, вы можете использовать ,.pipe(take(1)).toPromise
но как вы можете видеть здесь , это не рекомендуется.Поэтому, пожалуйста, используйте
toPromise
(RxJs 6), как сказано:Пример async / await:
Подробнее читайте здесь .
И удалите эту неправильную заявку, в которой говорится, что
toPromise
она устарела.источник
Используйте новый
firstValueFrom()
илиlastValueFrom()
вместоtoPromise()
, который, как указано здесь, устарел, начиная с RxJS 7, и будет удален в RxJS 8.Это доступно в RxJS 7+
См .: https://indepth.dev/rxjs-heads-up-topromise-is-being-deprecated/
источник