延迟Rxjs BehaviorSubject机制

时间:2018-03-22 12:57:25

标签: rxjs rxjs5

我有以下要求。

我有一个带有BehaviorSubject的Angular服务。 完成http请求,完成此操作后,将使用值调用BehaviorSubject.next方法。 此值可以在单页的生命周期内更改。

向其注册了不同的订阅者,并在此更改时调用。

问题是,当http请求处于挂起状态时,BehaviorSubject已经包含一个默认值,订阅者已经立即获得此值。

我想要的是订阅者必须等到http请求完成(延迟)并在http请求完成时获取值并设置值。 所以我需要的是某种延迟行为主体机制。

我如何使用rxjs实现这个?

另一个要求是,如果我在方法中订阅了behaviorubject,我们希望订阅者获得第一个非默认值并且订阅结束。我们不希望重新执行函数中的本地订阅。

2 个答案:

答案 0 :(得分:1)

在您的行为主题上使用过滤器,这样您的订阅者就不会获得第一个默认发布值:

mySubject$: BehaviorSubject<any> = new BehaviorSubject<any>(null);

httpResponse$: Observable<any> = this.mySubject$.pipe(
  filter(response => response)
  map(response => {
     const modifyResponse = response;
    // modify response
    return modifyResponse;
  }),
  take(1)
);
this.httpResponse$.subscribe(response => console.log(response));

this.myHttpCall().subscribe(response => this.mySubject$.next(response));

如果需要,您当然可以在方法中包装httpResponse $ observable。

答案 1 :(得分:0)

我认为你要立即推迟发出的默认值这一事实会让人怀疑为什么要使用BehaviorSubject。让我们记住:使用BehaviorSubject(而不是Subject或普通的Observable)的主要原因是向任何订阅者发送值

如果您需要一个Observable类型,您需要控制生产者(通过.next([value]))和/或您希望开箱即用多播订阅,那么主题是合适的。

如果,除此之外的其他要求是订阅者需要立即获得值,那么您需要考虑 BehaviorSubject

如果您没有说您需要更新其他非http事件/来源的值,那么我建议使用shareReplay(1)模式。尽管如此...

private cookieData$: Subject<RelevantDataType> = new 
Subject<RelevantDataType>(null);


// Function for triggering http request to update
// internal Subject.
// Consumers of the Subject can potentially invoke this 
// themselves if they receive 'null' or no value on subscribe to subject
public loadCookieData(): Observable<RelevantDataType> {
    this.http.get('http://someurl.com/api/endpoint')
        .map(mapDataToRelevantDataType());
}

// Function for dealing with updating the service's 
// internal cookieData$ Subject from external 
// consumer which need to update this value
// via non-http events
public setCookieData(data: any): void {
    const newCookieValue = this.mapToRelevantDataType(data); // <-- If necessary
    this.cookieData$.next(newCookieValue); // <-- updates val for all subscribers
}

get cookieData(): Observable<RelevantDataType> {
    return this.cookieData$.asObservable();
}

解决方案基于OP评论等。 - 处理订阅主题类型。 - 处理外部订户无法直接“接下来”新值 - 处理外部生产者能够在主题类型上设置新值 - 处理在http请求未决时未提供默认值