Angular rxjs私人主题+可公开观察的设置

时间:2018-11-02 16:44:57

标签: angular rxjs angular2-observables behaviorsubject

我是rxjs / observables的新手。他们有点让我烦恼,所以这可能是一个简单的问题。

我希望服务中有一个主题,可以经常触发该主题以获取更新。然后,更新可以立即返回给调用方(如果他们等待),也可以发送给任何订户。我希望该主题是私有的,因此只有该服务才能.next()

最后一个警告是,当某个对象订阅了可观察对象时,我希望立即获取当前值,然后在此之后收到任何更新的警报。我的菜鸟尝试如下。似乎大多数情况下都有效,但是页面订阅在初始订阅时每次next()的调用都会获得一次当前值。因此,如果getNewThings()被调用了5次,则页面订阅将立即获得当前主题值的5次。我该如何解决?

服务

@Injectable()
export class PretendService{
    private mySubject: BehaviorSubject<Thing[]> = new BehaviorSubject<Thing[]>(null);
    public readonly mySubjectObservable: Observable<Thing[]> = this.mySubject.asObservable();
    ...
    public getNewThings(): Promise<Thing[]>{
        let p = new Promise<Thing[]>((resolve, reject) => {

            //Do the work to get Thing[]s
            let theThings: Thing[] = [];
            mySubject.next(theThings);
            resolve(theThings);
        }

        return p;
    }
}

页面

...
thingSubscription: Subscription;
constructor(private pretendService: PretendService){
    this.thingSubscription = this.pretendService.mySubjectObservable.subscribe((things)=>{
        //ISSUE HERE: 
        //This fires once per .next() with the current value on initial subscription
        console.log(`got some things [{things}]`);
    });
}
...
//Unsubscribe in destructor...etc...

更新

这是一个显示其中一些内容的堆叠闪电战。单击主按钮将多次触发刷新方法。然后单击“其他页面”链接以触发订阅。注意,在Page2组件上有一个OnDestroy实现,可以对其进行注释/取消注释。那是我的主要问题-我没有正确销毁,所以它正在收集订阅。  https://stackblitz.com/edit/angular-umk8qm?embed=1&file=src/app/page2.component.ts

1 个答案:

答案 0 :(得分:0)

有关更新,请参见StackBlitz。就我而言,我没有正确实现OnDestroy,这导致我的应用累积了很多订阅。看来next()上的每个BehaviorSubject调用都获得1个更新。但是,它只是获得1,但是由于建立了许多订阅,因此好像1订阅正在获得多个更新。下面是一个更完整的实现。

页面

export class Page2Component implements OnDestroy
...
thingSubscription: Subscription;
constructor(private pretendService: PretendService){
    this.thingSubscription = this.pretendService.mySubjectObservable.subscribe((things)=>{
        console.log(`got some things [{things}]`);
    });
}
...
ngOnDestroy() {    
    //This should fire if things are destroying properly
    console.log('destroying!');
    this.thingSubscription && this.thingSubscription.unsubscribe();
}
....