简体   繁体   English

在BehaviorSubject中使用单个订阅变量

[英]Using a single subscription variable with BehaviorSubject

I use BehaviorSubject in my Angular app and I get observable to my Details component from DataService as shown below: 我在Angular应用程序中使用BehaviorSubject ,并且可以从DataService观察到Details组件,如下所示:

DataService.ts: DataService.ts:

export class DataService {

    private messageTracker = new BehaviorSubject<any>();
    private fileTracker = new BehaviorSubject<any>();

    getMessageTracker(): Observable<any> {
        return this.messageTracker.asObservable();
    }

    getFileTracker(): Observable<any> {
        return this.fileTracker.asObservable();
    }

    //set methods omitted for brevity
}


DetailComponent : DetailComponent:

export class DetailComponent implements OnInit {

    subscription; //??? Can I use this variable for every subscription below?

    constructor(private dataService: DataService) { }

    ngOnInit(): void {

        this.subscription = this.dataService.getMessageTracker().subscribe((param: any) => {
                //...  
        });

        this.subscription = this.dataService.getFileTracker().subscribe((param: any) => {
            //...
        });
    }
}

ngOnDestroy(): void {
    this.subscription.unsubscribe();
}

My questions are: 我的问题是:

1) As far as I know, as above, I should create a new BehaviorSubject variable for each event eg messageCreateTracker (for tracking a new message added), fileCreateTracker (for tracking a new file added, messageUpdateTracker (for tracking a message updated). Is that all true? 1)据我所知,如上所述,我应该为每个事件创建一个新的BehaviorSubject变量,例如messageCreateTracker (用于跟踪添加的新消息), fileCreateTracker (用于跟踪添加的新文件, messageUpdateTracker (用于跟踪更新的消息)。这是真的吗?

2) Looking DetailComponent , I just used a single subscription variable for every subscriptions of Observables . 2)在查看DetailComponent ,我仅对Observables每个订阅使用了一个subscription变量。 Is that a bad approach? 那是一个不好的方法吗? Should I create a new subscription variable for each subscriptions in ngOnInit() ? 是否应该为ngOnInit()每个订阅创建一个新的订阅变量?

Answer For Query 1: 回答查询1:

It depends on the developer's coding style , or how he thought, you can also pass the type of event and data with that, in that case, you will need only one BehaviorSubject , like this : 取决于开发人员的编码风格或他的想法,您还可以通过它传递事件和数据的类型,在这种情况下,您将只需要一个BehaviorSubject ,如下所示:

this.messageTracker.next({ type : 'create' ,  data });
this.messageTracker.next({ type : 'update' ,  data });
this.messageTracker.next({ type : 'delete' ,  data });

But this can also create a complexity if it goes large, gain depends on the requirements of the project, your way is also good . 但是,如果它变大, 也会造成复杂性 ,增益取决于项目的要求, 您的方法也不错


Answer For Query 2: 回答查询2:

Basically, you can't handle multiple subscriptions like that it will override the previous one and it will only unsubscribe the last one : 基本上,您不能像这样处理多个订阅,因为它将覆盖前一个订阅,并且只会取消订阅最后一个订阅:

So you can create multiple variables for that OR single array/object of your subscription and then unsubscribe all : 因此,您可以为订阅的那个OR单个数组/对象创建多个变量 ,然后全部取消订阅:

With Array : 使用数组:

this.subscription = [];
this.subscription.push(this.dataService.getMessageTracker().subscribe((param: any) => {}));    
this.subscription.push(this.dataService.getFileTracker().subscribe((param: any) => {}));

ngOnDestroy(): void {
    this.subscription.forEach(sub => {
        sub.unsubscribe();
    })
}

With Object : 与对象:

this.subscription = {};
this.subscription['messageTracker'] = this.dataService.getMessageTracker().subscribe((param: any) => {}));
this.subscription['fileTracker'] = this.dataService.getFileTracker().subscribe((param: any) => {}));

this.subscription['fileTracker'].unsubscribe(); // <--- You can also do
delete this.subscription['fileTracker']; // <--- then dont forgot to remove, or will throw error in ngOnDestroy

ngOnDestroy(): void {
    for(key in this.subscription) {
      this.subscription[key].unsubscribe();
    }
}

though marked answer is well explained, I want to share some of my thoughts here. 尽管标记的答案已得到很好的解释,但我想在这里分享我的一些想法。

Question 1 问题1

  • It is better to create new BehaviorSubject object when you consider code maintenance and readability. 考虑代码维护和可读性时,最好创建新的BehaviorSubject对象。
  • Instantly notify anything that is subscribed to the BehaviorSubject when the data changes. 数据更改时,立即通知订阅到BehaviorSubject任何内容。 This will give you more complexity if you try to deal with different type of data with one object. 如果您尝试使用一个对象处理不同类型的数据,这将给您带来更多的复杂性。

Question 2 问题2

As @Vivek pointed out your this.subscription will be override the last subscription on every new subscribe. 正如@Vivek指出的那样,您的this.subscription将覆盖每个新订阅的最后一个订阅。

for this you can use Subscription class, 为此,您可以使用Subscription类,

Represents a disposable resource, such as the execution of an Observable. 表示一次性资源,例如Observable的执行。 A Subscription has one important method, unsubscribe, that takes no argument and just disposes the resource held by the subscription. 订阅具有一种重要的方法,即取消订阅,该方法不带任何参数,而只是处置该订阅所拥有的资源。

you can use this in two ways, 您可以通过两种方式使用它,

  • you can directly push the subscription to Subscription Array 您可以直接将订阅推送到订阅数组

      subscriptions:Subscription[] = []; ngOnInit(): void { this.subscription.push(this.dataService.getMessageTracker().subscribe((param: any) => { //... })); this.subscription.push(this.dataService.getFileTracker().subscribe((param: any) => { //... })); } ngOnDestroy(){ // prevent memory leak when component destroyed this.subscriptions.forEach(s => s.unsubscribe()); } 
  • using add() of Subscription 使用Subscription add()

     subscriptions = new Subscription(); this.subscriptions.add(subscribeOne); this.subscriptions.add(subscribeTwo); ngOnDestroy() { this.subscriptions.unsubscribe(); } 

A Subscription can hold child subscriptions and safely unsubscribe them all. Subscription可以保留子订阅,并可以安全地取消订阅所有子订阅。 This method handles possible errors (eg if any child subscriptions are null). 此方法处理可能的错误(例如,如果任何子订阅为空)。

Hope this helps.. :) 希望这可以帮助.. :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM