我怎么能“等待”一个可观察的处方?

我希望能够等待观察,例如。

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

幼稚的尝试会导致等待解析立即出现,而不会阻塞执行

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

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

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

145702 次浏览

你必须向 await传递一个承诺。将观察到的下一个事件转换为一个承诺,并等待它。

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

编辑注释: 这个答案最初使用。取(1)而改为使用。First ()避免了当流在一个值通过之前结束时从未解决的许诺问题。

从 RxJSv8开始,toPromise将被删除。相反,上面的代码可以被 await firstValueFrom(observable)代替

你将需要 await一个承诺,所以你将要使用 toPromise()。有关 toPromise()的详细信息,请参阅 这个

很有可能

await observable.first().toPromise();

正如之前的评论中指出的那样,当有空的完全可观测值时,take(1)first()操作符之间存在实质性的差异。

Observable.empty().first().toPromise()将导致与 EmptyError的拒绝,可以进行相应的处理,因为实际上没有值。

Observable.empty().take(1).toPromise()将得到具有 undefined值的分辨率。

编辑:

.toPromise()现在在 RxJS7中已被弃用(资料来源: https://rxjs.dev/deprecations/to-promise)

新答案:

作为不推荐的 to灭()方法的替代方法,您应该使用 内置在静态转换函数 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);

阅读更多 给你

使用新的 firstValueFrom()lastValueFrom()而不是 toPromise(),正如这里指出的,从 RxJS7开始就不推荐使用 toPromise(),并且将在 RxJS8中删除它们。

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


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

这在 RxJS7 + 中可用

见: https://indepth.dev/rxjs-heads-up-topromise-is-being-deprecated/

不推荐使用 toPromise(),因为它在 RxJs 7以后会被折旧。您可以使用 RxJs7lastValueFrom()firstValueFrom()中出现的两个新运算符。更多细节可以找到 给你

const result = await lastValueFrom(myObservable$);

测试版本的实现可以在这里找到:

我使用的是 RxJSV6.4.0,因此我应该在 V7.x.x toPromise()中使用不推荐的版本。受其他答案的启发,下面是我对 toPromise()所做的

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


...


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


...


请注意我是如何在 pipe()中使用 last()的。因为在我的 observable.first()中不能像 Macil中提到的那样工作

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

谢谢。