延迟Rxjs BehaviorSubject机制

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了延迟Rxjs BehaviorSubject机制相关的知识,希望对你有一定的参考价值。

我有以下要求。

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

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

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

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

我将如何使用rxjs实现这一点?

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

答案

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

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。

另一答案

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

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

如果除此之外的额外要求是订户需要立即获得值,那么您需要考虑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请求未决时未提供默认值

以上是关于延迟Rxjs BehaviorSubject机制的主要内容,如果未能解决你的问题,请参考以下文章

RxJS - BehaviorSubject,onComplete 未调用

使用 rxjs5 获取 BehaviorSubject 当前值的简单方法

javascript 使用BehaviorSubject的同步RxJS不正确

RxJS 5,将 observable 转换为 BehaviorSubject(?)

Angular 7 rxjs BehaviorSubject 发出重复值

BehaviorSubject 和条件组件显示