158

我希望能够等待一个可观察的,例如

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

天真的尝试会导致 await 立即解决并且不会阻塞执行

编辑:我的完整预期用例的伪代码是:

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

我知道我可以将其他代码移动到另一个单独的函数中并将其传递给订阅回调,但我希望能够避免这种情况。

4

7 回答 7

184

你必须向await. 将 observable 的下一个事件转换为一个 Promise 并等待它。

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

编辑说明:此答案最初使用 .take(1) 但已更改为使用 .first() 这避免了如果流在值通过之前结束,Promise 永远不会解决的问题。

从 RxJS v8 开始,toPromise将被删除。相反,上面可以替换为await firstValueFrom(observable)

于 2015-12-09T23:25:10.763 回答
40

使用新的firstValueFrom()orlastValueFrom()代替toPromise(),正如这里所指出的,从 RxJS 7 开始不推荐使用,并将在 RxJS 8 中删除。

import { firstValueFrom} from 'rxjs';
import { lastValueFrom } from 'rxjs';

this.myProp = await firstValueFrom(myObservable$);
this.myProp = await lastValueFrom(myObservable$);

这在 RxJS 7+ 中可用

请参阅:https ://indepth.dev/rxjs-heads-up-topromise-is-being-deprecated/

于 2020-09-04T16:27:50.563 回答
29

它可能必须是

await observable.first().toPromise();

正如之前在评论中指出的那样,当有空的已完成的 observable 时,take(1)和运算符之间存在很大差异。first()

Observable.empty().first().toPromise()将导致拒绝EmptyError,可以相应地处理,因为确实没有任何价值。

并将Observable.empty().take(1).toPromise()导致具有undefined价值的解决方案。

于 2017-05-30T09:24:00.683 回答
12

你需要await一个承诺,所以你会想要使用toPromise(). 有关. _ _toPromise()

于 2015-12-09T23:52:55.867 回答
12

编辑:

.toPromise()现在在 RxJS 7 中已弃用(来源:https ://rxjs.dev/deprecations/to-promise )

新答案:

作为已弃用的 toPromise() 方法的替代,您应该使用两个内置静态转换函数 firstValueFrom 或 lastValueFrom 之一。

例子:

import { interval, lastValueFrom } from 'rxjs';
import { take } from 'rxjs/operators';
 
async function execute() {
  const source$ = interval(2000).pipe(take(10));
  const finalNumber = await lastValueFrom(source$);
  console.log(`The final number is ${finalNumber}`);
}
 
execute();
 
// Expected output:
// "The final number is 9"

老答案:

如果toPromise不推荐使用,您可以使用.pipe(take(1)).toPromise,但正如您在此处看到的,它没有被弃用。

因此,请toPromise按上述方式使用 (RxJs 6):

//return basic observable
const sample = val => Rx.Observable.of(val).delay(5000);
//convert basic observable to promise
const example = sample('First Example')
  .toPromise()
  //output: 'First Example'
  .then(result => {
    console.log('From Promise:', result);
  });

异步/等待示例:

//return basic observable
const sample = val => Rx.Observable.of(val).delay(5000);
//convert basic observable to promise
const example = await sample('First Example').toPromise()
// output: 'First Example'
console.log('From Promise:', result);

在这里阅读更多。

于 2020-01-03T16:03:07.583 回答
3

不推荐使用toPromise()它,因为它在 RxJs 7 以后开始贬值。您可以使用 RxJs 7lastValueFrom()firstValueFrom(). 更多细节可以在这里找到

const result = await lastValueFrom(myObservable$);

Beta 版的实现可在此处获得:

于 2021-02-01T09:35:21.663 回答
0

我正在使用 RxJS V 6.4.0,因此我应该在 V 7.xx 中使用已弃用的一个toPromise()。受其他答案的启发,这就是我所做的toPromise()

import { first, ... } from 'rxjs/operators';

...

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

...

注意我是如何last()pipe(). 因为我observable.first()的不能像macil提到的那样工作

希望这可以帮助像我一样使用 RxJS V 6.xx 的其他人:)。

谢谢。

于 2021-12-19T07:11:58.963 回答