如何在Rx Observable上“等待”?

时间:2015-12-09 22:40:53

标签: javascript rxjs ecmascript-7

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

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

天真的尝试会导致等待立即解决并且不会阻止执行

编辑: 我的完整用途的伪代码是:

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

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

6 个答案:

答案 0 :(得分:88)

您必须将承诺传递给await。将可观察的下一个事件转换为承诺并等待该事件。

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

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

答案 1 :(得分:21)

必须是

await observable.first().toPromise();

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

Observable.empty().first().toPromise()会导致EmptyError拒绝可以相应处理,这通常是理想的行为。

Observable.empty().take(1).toPromise()将导致未决承诺,这是可取的......几乎从不。

答案 2 :(得分:8)

您需要await一个承诺,因此您需要使用toPromise()。有关toPromise()的详细信息,请参阅this

答案 3 :(得分:4)

如果您不推荐使用toPromise,则可以使用.pipe(take(1)).toPromise,但是您可以看到here并不推荐使用。

因此,请按照以下说明使用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);

了解更多here

并且请删除这个错误的说法,说toPromise已过时。

答案 4 :(得分:4)

使用新的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/

答案 5 :(得分:2)

不建议使用 export const createPostAction = (newPostData) => async (dispatch) => { try { await createPost(newPostData); const { data } = await getAllPosts(); const action = { type: 'GET_ALL', payload: data, } dispatch(action); } catch (error) { console.log(error.message); } } ,因为它在 RxJs 7 以后会贬值。您可以使用 RxJs 7 toPromise()lastValueFrom() 中存在的两个新运算符。更多详情请见here

firstValueFrom()

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