繁体   English   中英

我如何在 Rx Observable 上“等待”?

[英]How can I `await` on an Rx Observable?

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

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

天真的尝试导致等待立即解决而不是阻止执行

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

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

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

你必须通过一个 promise 来await 将 observable 的下一个事件转换为 promise 并等待它。

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

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

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

它可能必须是

await observable.first().toPromise();

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

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

Observable.empty().take(1).toPromise()将导致解析值undefined

使用新的firstValueFrom()lastValueFrom()而不是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/

您将需要await承诺,因此您需要使用toPromise() 为更多细节toPromise()

如果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);

在这里阅读更多。

并且请删除这个错误的声明,说toPromise已被弃用。

不推荐使用toPromise()因为它在 RxJs 7 之后会贬值。 您可以使用 RxJs 7 lastValueFrom()firstValueFrom()存在的两个新运算符。 可以在此处找到更多详细信息

const result = await lastValueFrom(myObservable$);

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

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

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

...

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

...

请注意我如何在pipe()使用last() pipe() 因为在我的observable.first()上不像macil提到的那样工作

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

谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM