Angular 角度及;RX:改进订阅收集

Angular 角度及;RX:改进订阅收集,angular,typescript,rxjs,rxjs5,Angular,Typescript,Rxjs,Rxjs5,更新 找到解决方案后,我根据公认的答案编写了一个小助手,使其更易于使用。希望它能帮助那些一次又一次面临同样问题的人 原始问题 假设我们有一个组件,在热观测上有两个订阅。我们在ngOnInit中订阅它们,并在ngondestory中取消订阅,以避免内存泄漏/意外行为: public ngOnInit() { this.s1 = o1.subscribe(console.debug.bind(console)); this.s2 = o2.subscribe(console.debug.bi

更新

找到解决方案后,我根据公认的答案编写了一个小助手,使其更易于使用。希望它能帮助那些一次又一次面临同样问题的人

原始问题

假设我们有一个组件,在热观测上有两个订阅。我们在
ngOnInit
中订阅它们,并在
ngondestory
中取消订阅,以避免内存泄漏/意外行为:

public ngOnInit() {
  this.s1 = o1.subscribe(console.debug.bind(console));
  this.s2 = o2.subscribe(console.debug.bind(console));
}

public ngOnDestroy() {
  this.s1.unsubscribe();
  this.s2.unsubscribe();
}
我喜欢Rx,但每次我需要遵循以下步骤时,我都想自杀:

  • 为每个订阅创建专用订阅属性
  • 将此属性分配给订阅(这看起来非常难看,因为实际逻辑位于右侧)
  • 在销毁时取消订阅每个订阅
  • 有什么办法可以改进这一点吗

    例如,在RxSwift中,他们有一个
    DisposeBag
    ,为了改进流程,翻译成typescript将是:

    private let bag = DisposeBag();
    
    ...
    
    o1.subscribe(...).addDisposableTo(bag);
    
    然后只摧毁它一次。问题是我找不到任何类似的
    订阅
    功能

    欢迎提出任何想法/提示。

    您可以这样做:

    private teardown$ = new Subject<void>();
    
    public ngOnInit() {
        o1.takeUntil(this.teardown$).subscribe(console.debug.bind(console));
        o2.takeUntil(this.teardown$).subscribe(console.debug.bind(console));
    }
    
    public ngOnDestroy() {
       this.teardown$.next();
    }
    
    private teardown$=新主题();
    公共ngOnInit(){
    o1.takeUntil(this.teardown$).subscribe(console.debug.bind(console));
    o2.takeUntil(this.teardown$).subscribe(console.debug.bind(console));
    }
    公共恩格德斯特罗(){
    this.teardown$.next();
    }
    
    您描述的内容在RxJS 4(如果我错了,请纠正我)或RxPHP中也被称为“一次性”。在RxJS 5中,这称为订阅,但目的完全相同

    在下面的例子中,我有两个源观测值。我用一个
    Subscription
    对象包装他们的两个unsubscribe调用,该对象将回调作为调用其
    unsubscribe()方法时使用的参数

    var source1 = Observable.interval(250);
    var source2 = Observable.interval(350);
    
    let sub1 = source1.subscribe(val => console.log(val));
    let sub2 = source2.subscribe(val => console.log(val));
    
    let subscriptions = new Subscription(() => {
        sub1.unsubscribe();
        sub2.unsubscribe();
    });
    
    setTimeout(() => {
        subscriptions.unsubscribe();
    }, 3000);
    
    同样,我也可以从
    source1.subscribe
    获取第一个
    Subscription
    ,然后添加另一个
    Subscription
    ,该订阅将与其自己的
    unsubscribe()
    调用一起使用
    add()
    方法调用:

    var source1 = Observable.interval(250);
    var source2 = Observable.interval(350);
    
    let subscriptions = source1.subscribe(val => console.log(val));
    subscriptions.add(source2.subscribe(val => console.log(val)));
    
    setTimeout(() => {
        subscriptions.unsubscribe();
    }, 3000);
    

    有关更多信息,请查看源代码:

    您可以在超类中创建一个数组,并将订阅推送到该数组。然后在超级类
    ngondestory
    上,您可以
    取消订阅数组元素。这并不能解决我需要将整个可观察对象包装到括号中等问题。我已经尝试过这种方法,甚至编写了一个小的装饰程序,它可以自动完成,然而,它并没有看起来更好。这看起来真的很整洁,感觉和我要找的东西一模一样。非常感谢你!你知道有哪家图书馆能用这种方法解决这个问题吗?不客气!我还不知道有哪家图书馆,但我也有兴趣拥有一家现在你可以使用它:)如果你知道一些改进的方法,请让我知道。。。