通过distinctUntilChanged发射的rxjs行为主体

通过distinctUntilChanged发射的rxjs行为主体,rxjs,observable,Rxjs,Observable,我想实现一个具有3个特定属性的可观察/主体 记住最后发出的值,并能够通过getter(BehaviorSubject)将其显示出来 仅在值更改时发射 它必须有一个强类型,以便消费者知道getter是可用的(aka.BehaviorSubject.getValue()) 我正在考虑扩展BehaviorSubject,但希望确保我没有根据新手的理解引入任何潜在的陷阱 export class DistinctUntilChangedBehaviorSubject<T, TValue> e

我想实现一个具有3个特定属性的可观察/主体

  • 记住最后发出的值,并能够通过getter(BehaviorSubject)将其显示出来
  • 仅在值更改时发射
  • 它必须有一个强类型,以便消费者知道getter是可用的(aka.BehaviorSubject.getValue())
  • 我正在考虑扩展BehaviorSubject,但希望确保我没有根据新手的理解引入任何潜在的陷阱

    export class DistinctUntilChangedBehaviorSubject<T, TValue> extends BehaviorSubject<T> {
        constructor(
            initialValue: T,
            private _distinctKeySelector?: (value: T) => TValue,
            private _comparer?: _Comparer<TValue, boolean>
        ) {
            super(initialValue);
        }
    
        public subscribe() {
            // I'm particularly interested in knowing if this has any gotchas. 
            // Mostly things like creating subscriptions that don't get disposed as expected.
            return super.distinctUntilChanged(
                this._distinctKeySelector,
                this._comparer
            ).subscribe.apply(this, arguments);
        }
    }
    
    导出类distinctuntillchangedBehaviorSubject扩展了BehaviorSubject{
    建造师(
    初始值:T,
    private _distinctKeySelector?:(值:T)=>TValue,
    专用比较器?:\u比较器
    ) {
    超级(初始值);
    }
    公众订阅(){
    //我特别想知道这是否有什么问题。
    //大多数情况下,像创建订阅这样的事情并没有得到预期的处理。
    返回super.distinctUntilChanged(
    这是一个独特的键盘选择器,
    这是比较器
    ).订阅.应用(此,参数);
    }
    }
    
    因此,有两个问题:

  • 这似乎是一个合理的方法/这里有什么问题吗
  • 有没有其他更好的方法

  • 我不知道真正的原因,但我倾向于选择组合而不是扩展

    所以我会按照这些思路做一些事情

    import {BehaviorSubject} from 'rxjs';
    
    export class BehaviourSubjectAugmented<T> {
        bs: BehaviorSubject<T>;
    
        constructor(initialValue: T, private comparer: (p: T, q: T) => boolean) {
            this.bs = new BehaviorSubject(initialValue);
        }
    
        getValue() {
            return this.bs.getValue();
        }
    
        asObservable() {
            return this.bs.asObservable()
                            .distinctUntilChanged(this.comparer);
        }
    
        complete() {
            return this.bs.complete();
        }
        next(value: T) {
            return this.bs.next(value);
        }
    
    }
    
    从'rxjs'导入{BehaviorSubject};
    导出类行为主体增强{
    bs:行为主体;
    构造函数(initialValue:T,私有比较器:(p:T,q:T)=>boolean){
    this.bs=新行为主体(初始值);
    }
    getValue(){
    返回此.bs.getValue();
    }
    asObservable(){
    返回此.bs.asObservable()
    .distinctUntilChanged(此.comparer);
    }
    完成(){
    返回此.bs.complete();
    }
    下一个(值:T){
    返回此.bs.next(值);
    }
    }
    
    我不知道真正的原因,但我倾向于组合而不是扩展

    所以我会按照这些思路做一些事情

    import {BehaviorSubject} from 'rxjs';
    
    export class BehaviourSubjectAugmented<T> {
        bs: BehaviorSubject<T>;
    
        constructor(initialValue: T, private comparer: (p: T, q: T) => boolean) {
            this.bs = new BehaviorSubject(initialValue);
        }
    
        getValue() {
            return this.bs.getValue();
        }
    
        asObservable() {
            return this.bs.asObservable()
                            .distinctUntilChanged(this.comparer);
        }
    
        complete() {
            return this.bs.complete();
        }
        next(value: T) {
            return this.bs.next(value);
        }
    
    }
    
    从'rxjs'导入{BehaviorSubject};
    导出类行为主体增强{
    bs:行为主体;
    构造函数(initialValue:T,私有比较器:(p:T,q:T)=>boolean){
    this.bs=新行为主体(初始值);
    }
    getValue(){
    返回此.bs.getValue();
    }
    asObservable(){
    返回此.bs.asObservable()
    .distinctUntilChanged(此.comparer);
    }
    完成(){
    返回此.bs.complete();
    }
    下一个(值:T){
    返回此.bs.next(值);
    }
    }
    
    我原来的想法导致了调用堆栈超出问题。我假设distinctUntilChanged必须在内部调用subscribe,从而导致无限递归

    我最终找到了一种更简单的方法,通过简单地向一个ISubject实例添加一个方法来获得所需的内容

    function distinctUntilChangedBehaviorSubject(
        initialValue: number
    ): ISubject<number> & { getValue(): number } {
        const observer = new BehaviorSubject<number>(initialValue);
        const observable = observer.distinctUntilChanged();
    
        const subject: ISubject<number> = Subject.create(
            observer,
            observable
        );
    
        return Object.assign(
            subject,
            {
                getValue: () => observer.getValue()
            }
        );
    }
    
    函数distinctuntillchangedbehaviorsubject(
    初始值:数字
    ):ISubject&{getValue():number}{
    const observer=新行为主体(初始值);
    const observable=observer.distinctUntilChanged();
    const subject:ISubject=subject.create(
    观察者
    可观察
    );
    返回Object.assign(
    主题,,
    {
    getValue:()=>observer.getValue()
    }
    );
    }
    
    我原来的想法导致了调用堆栈超出问题。我假设distinctUntilChanged必须在内部调用subscribe,从而导致无限递归

    我最终找到了一种更简单的方法,通过简单地向一个ISubject实例添加一个方法来获得所需的内容

    function distinctUntilChangedBehaviorSubject(
        initialValue: number
    ): ISubject<number> & { getValue(): number } {
        const observer = new BehaviorSubject<number>(initialValue);
        const observable = observer.distinctUntilChanged();
    
        const subject: ISubject<number> = Subject.create(
            observer,
            observable
        );
    
        return Object.assign(
            subject,
            {
                getValue: () => observer.getValue()
            }
        );
    }
    
    函数distinctuntillchangedbehaviorsubject(
    初始值:数字
    ):ISubject&{getValue():number}{
    const observer=新行为主体(初始值);
    const observable=observer.distinctUntilChanged();
    const subject:ISubject=subject.create(
    观察者
    可观察
    );
    返回Object.assign(
    主题,,
    {
    getValue:()=>observer.getValue()
    }
    );
    }
    
    我也倾向于选择组合,只是不想包装太多东西。在您的示例中,当您订阅BehaviorSubjectAugmented对象时是否会调用asObservable(),或者您是否必须订阅asObservable()的结果?正如现在编码的那样,您需要执行
    BehaviorSubjectAugmented.asObservable().subscribe()
    .Hmm,猜测这也意味着除非调用asObservable,否则链式运算符不会出现。
    asObservable()
    确保不能使用
    next
    方法发出值(请参阅或)。如果这对你来说并不重要,那么你可以直接使用
    bs
    property。我也倾向于选择组合,只是不想包装太多东西。在您的示例中,当您订阅BehaviorSubjectAugmented对象时是否会调用asObservable(),或者您是否必须订阅asObservable()的结果?正如现在编码的那样,您需要执行
    BehaviorSubjectAugmented.asObservable().subscribe()
    .Hmm,猜测这也意味着除非调用asObservable,否则链式运算符不会出现。
    asObservable()
    确保不能使用
    next
    方法发出值(请参阅或)。如果这对您不重要,那么您可以直接使用
    bs
    属性