如何在 Angular2 中取消订阅

IT技术 javascript angular rxjs
2021-03-18 22:01:11

如何取消 Angular2 中的订阅?RxJS 似乎有一个 dispose 方法,但我不知道如何访问它。所以我有可以访问 EventEmitter 并订阅它的代码,如下所示:

var mySubscription = someEventEmitter.subscribe(
    (val) => {
        console.log('Received:', val);
    },
    (err) => {
        console.log('Received error:', err);
    },
    () => {
        console.log('Completed');
    }
);

如何使用mySubscription取消订阅?

6个回答

您要取消订阅吗?

mySubscription.unsubscribe();
好主。我发誓我已经试过了。我查看了 RxJS 源代码,这似乎就是它的内容。我一定是有一个不同的错误导致了我的问题。谢谢。
2021-04-23 22:01:11
@paraditeimport { Subscription } from "rxjs";和取消订阅if (!mySubscription.closed) { mySubscription.unsubscribe(); }
2021-04-29 22:01:11
import { Subscription } from 'rxjs/Subscription'; 将有助于减小您的包裹尺寸
2021-05-03 22:01:11
这很好用,但我很好奇mySubscriptionTypeScript 中的类型是什么我想避免mySubscription: any在课堂上写作
2021-05-14 22:01:11

我以为我也投入了两美分。我使用这种模式:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';

@Component({
    selector: 'my-component',
    templateUrl: 'my.component.html'
})
export class MyComponent implements OnInit, OnDestroy {

    private subscriptions: Array<Subscription> = [];

    public ngOnInit(): void {
        this.subscriptions.push(this.someService.change.subscribe(() => {
            [...]
        }));

        this.subscriptions.push(this.someOtherService.select.subscribe(() => {
            [...]
        }));
    }

    public ngOnDestroy(): void {
        this.subscriptions.forEach((subscription: Subscription) => {
            subscription.unsubscribe();
        });
    }
}

编辑

前几天我阅读了文档,发现了一个更推荐的模式:

ReactiveX/RxJS/订阅

优点:

它在内部管理新订阅并添加一些整洁的检查。在功能中更喜欢这种方法:)。

缺点:

代码流是什么以及订阅如何受到影响并不是 100% 清楚的。也不清楚(仅从代码来看)它如何处理关闭的订阅以及如果取消订阅是否所有订阅都被关闭。

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';

@Component({
    selector: 'my-component',
    templateUrl: 'my.component.html'
})
export class MyComponent implements OnInit, OnDestroy {

    private subscription: Subscription = new Subscription();

    public ngOnInit(): void {
        this.subscription.add(this.someService.change.subscribe(() => {
            [...]
        }));

        this.subscription.add(this.someOtherService.select.subscribe(() => {
            [...]
        }));
    }

    public ngOnDestroy(): void {
        /*
         * magic kicks in here: All subscriptions which were added
         * with "subscription.add" are canceled too!
         */
        this.subscription.unsubscribe();
    }
}
您可能会对另一种清晰的方法感兴趣。使用takeWhile运算符。此处描述的方法:brianflove.com/2016/12/11/anguar-2-unsubscribe-observables
2021-04-23 22:01:11
我也使用它,它可以很好地扩展您在组件中拥有的订阅量。
2021-04-28 22:01:11
没有“魔法” - 它是设计使然:“订阅也可以放在一起,因此对一个订阅的 unsubscribe() 的调用可能会取消订阅多个订阅。您可以通过将一个订阅“添加”到另一个订阅中来做到这一点:” github。 com/ReactiveX/rxjs/blob/master/doc/subscription.md
2021-04-29 22:01:11
查看使用 takeUntil替代解决方案有一个丰富而有趣的讨论,考虑不同的选择。
2021-05-10 22:01:11

编辑:这不适用于 RxJS 5,这是 angular2 正在使用的。

我原以为您正在寻找Disposable上的 dispose 方法

subscribe 方法返回一个 Disposable(链接

我似乎无法在文档中更明确地找到它,但这有效(jsbin):

var observable = Rx.Observable.interval(100);

var subscription = observable.subscribe(function(value) {
   console.log(value);
});

setTimeout(function() {
  subscription.dispose();           
}, 1000)

奇怪的是,取消订阅似乎对你有用,而对我不起作用......

您可能使用不同的版本。Angular2 在 Rxjs5 上不是吗?
2021-04-29 22:01:11
而已。可以在这里找到进行了更改以符合ES7 Observable 规范
2021-05-10 22:01:11
是的,Angular 2 使用 RxJS 5。
2021-05-14 22:01:11

关于取消订阅 ng2 的 Observables 有太多不同的解释,我花了很长时间才找到正确的答案。下面是一个工作示例(我试图限制鼠标移动)。

import {Injectable, OnDestroy} from "@angular/core";
import {Subscription} from "rxjs";

@Injectable()
export class MyClass implements OnDestroy {
  
  mouseSubscription: Subscription; //Set a variable for your subscription
  
  myFunct() {
    // I'm trying to throttle mousemove
    const eachSecond$ = Observable.timer(0, 1000);
    const mouseMove$ = Observable.fromEvent<MouseEvent>(document, 'mousemove');
    const mouseMoveEachSecond$ = mouseMove$.sample(eachSecond$);
    
    this.mouseSubscription = mouseMoveEachSecond$.subscribe(() => this.doSomethingElse());
  }

  doSomethingElse() {
    console.log("mouse moved");
  }
  
  stopNow() {
    this.mouseSubscription.unsubscribe();
  }
  
  ngOnDestroy() {
    this.mouseSubscription.unsubscribe();
  }
  
}

ngOnDestroy(){
   mySubscription.unsubscribe();
}

最好在销毁组件时取消订阅 rxjs 取消订阅,即从 DOM 中删除以避免不必要的内存泄漏