首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RxJS 5,将可观测值转换为BehaviorSubject(?)

RxJS 5,将可观测值转换为BehaviorSubject(?)
EN

Stack Overflow用户
提问于 2017-09-13 22:14:20
回答 3查看 9.9K关注 0票数 21

我有一个可以观察到的父值,一旦它有了订阅服务器,它就会执行一个查找并发出一个值,然后完成。

我想把它转换成一个可观察的(或行为主体或其他有用的东西),这样做如下:一旦它至少有一个订阅者,它就会从可观察的父用户那里得到结果(一次)。然后,当所有订阅者订阅时,它会向所有订阅者发出该值,并向所有未来订阅者发出该值。它应该继续这种行为,即使它的订户计数下降到零。

这看起来应该很容易。以下是不起作用的地方:

代码语言:javascript
复制
theValue$: Observable<boolean> = parent$
.take(1)
.share()

其他不起作用的事情:publishReplay()publish()。效果更好的东西:

代码语言:javascript
复制
theValue$ = new BehaviorSubject<boolean>(false);

parent$
.take(1)
.subscribe( value => theValue$.next(value));

但是,这种方法存在一个问题:parent$theValue$获得第一个订阅服务器之前就被订阅了。

有更好的方法来处理这件事吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-09-13 22:31:10

shareReplay应该做您想做的事情:

代码语言:javascript
复制
import 'rxjs/add/operator/shareReplay';
...
theValue$: Observable<boolean> = parent$.shareReplay(1);

shareReplay是在RxJS版本5.4.0中添加的。它返回一个可观察到的引用,它将在第一次订阅时订阅源parent$。在源完成后进行的订阅将接收重放通知。

shareReplayrefCount在我最近写的一篇文章中作了更详细的解释:RxJS:如何使用refCount

票数 17
EN

Stack Overflow用户

发布于 2019-02-17 09:54:49

我已经实现了一种将可观测值转换为BehaviorSubjects的方法,因为我认为shareReplay方法对于将来的参考并不是非常容易读的

代码语言:javascript
复制
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

export function convertObservableToBehaviorSubject<T>(observable: Observable<T>, initValue: T): BehaviorSubject<T> {
    const subject = new BehaviorSubject(initValue);

    observable.subscribe(
        (x: T) => {
            subject.next(x);
        },
        (err: any) => {
            subject.error(err);
        },
        () => {
            subject.complete();
        },
    );

    return subject;
}
票数 10
EN

Stack Overflow用户

发布于 2019-11-13 10:20:29

这是tmuechsch的回答的一个改进变体。

代码语言:javascript
复制
import { Observable, BehaviorSubject } from 'rxjs';

export function convertObservableToBehaviorSubject<T>(observable: Observable<T>, initValue: T): BehaviorSubject<T> {
  const subject = new BehaviorSubject(initValue);
  const subscription = observable.subscribe(subject);
  return {
    subject,
    stopWatching: () => subscription.unsubscribe()
  };
}

要小心,因为返回的主题永远不会从可观察到的源中取消订阅。当您知道不再有对stopWatching的引用时,需要手动调用subject (例如,当视图组件被销毁/卸载时)。否则你会有内存泄漏。

对于给定的问题,不可能给出一个绝对安全的解决方案。原因是行为主题具有一个value属性,即使主题未被订阅,也必须始终更新该属性,因此,当每个人都取消订阅subject时,您就不能自动取消订阅subject

卡佩特氏解决方案也不完美,因为结果不是instanceof BehaviorSubject,只有在订阅时shareReplay才会记录值。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46207592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档