首页 > 解决方案 > RxJS 主题/可观察问题

问题描述

我正在尝试将 Angular 函数转换为可观察模式,因为它的当前实现与它有一些异步性。为了讨论的目的,举这个简单的例子。

aFunction(x: boolean){
    if(x){
        // ... do something asynchronous based on the value of x
    }
}

可以通过以下方式将其转换为使用 Observable:

anObservableFunction(x: boolean): Observable<any> {
    const result = new Subject();
    if(x){
        // ... do something asynchronous based on the value of x
        // ... where once the actual value you want to return to 
        // the subscribing functions, you can pass in the 
        // result.next(value);
        // result.complete();
    }
    return result.asObservable();
}

我面临的问题(据我的理解)是针对未访问内部选择语句的情况。

anObservableFunction(x: boolean): Observable<any> {
    const result = new Subject();
    if(x){
        // ... do something asynchronous based on the value of x
        // ... where once the actual value you want to return to 
        // the subscribing functions, you can pass in the 
        // result.next(value);
        // result.complete();
    } else {
        // here
    }
    return result.asObservable();
}

如果使用常规主题,订阅函数肯定不会获得任何值,因为事件的顺序是:

如果使用 BehaviorSubject 或 ReplaySubject,它们的初始/构造值将被保留,导致订阅事件不必要地触发?

标签: angularrxjsobservable

解决方案


如果值是同步发出的,那么使用 Subject 会出现问题是正确的。BehaviorSubject 具有不必要的初始值的缺点,但 ReplaySubject 实际上没有该值并且可以工作,但如果有人稍后订阅您可能不想要的方式,它也会重播此值。

一个简单的技巧是将同步发射延迟一个滴答声:

setTimeout(() => result$.next(42), 0);

但是,您也可以直接返回 observable 并避免使用主题:

foo(x) {
  if(x) {
    return callRemoteEndpoint();
  }

  return of(42);
} 

推荐阅读