簡體   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