Angular rxjs 私有主题 + public 可观察设置
Angular rxjs private subject + public observable setup
我是 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...
更新
这是一个显示其中一些内容的 stackblitz。点击主按钮会多次触发刷新方法。然后点击"Other Page"link触发订阅。请注意,在 Page2 组件上有一个可以是 commented/uncommented 的 OnDestroy
实现。那是我的主要问题 - 我没有正确销毁,所以它正在收集订阅。
https://stackblitz.com/edit/angular-umk8qm?embed=1&file=src/app/page2.component.ts
查看更新中的 StackBlitz。在我的例子中,我没有正确实施 OnDestroy
,这导致我的应用程序累积了订阅。看起来它在 BehaviorSubject
上每次 next()
调用都会获得 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();
}
....
我是 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...
更新
这是一个显示其中一些内容的 stackblitz。点击主按钮会多次触发刷新方法。然后点击"Other Page"link触发订阅。请注意,在 Page2 组件上有一个可以是 commented/uncommented 的 OnDestroy
实现。那是我的主要问题 - 我没有正确销毁,所以它正在收集订阅。
https://stackblitz.com/edit/angular-umk8qm?embed=1&file=src/app/page2.component.ts
查看更新中的 StackBlitz。在我的例子中,我没有正确实施 OnDestroy
,这导致我的应用程序累积了订阅。看起来它在 BehaviorSubject
上每次 next()
调用都会获得 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();
}
....