簡體   English   中英

如何在 Angular2 中取消訂閱

[英]How to cancel a subscription in Angular2

如何取消 Angular2 中的訂閱? RxJS 似乎有一個 dispose 方法,但我不知道如何訪問它。 所以我有可以訪問 EventEmitter 並訂閱它的代碼,如下所示:

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

如何使用mySubscription取消訂閱?

您要取消訂閱嗎?

mySubscription.unsubscribe();

我以為我也投入了兩美分。 我使用這種模式:

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();
    }
}

編輯:這不適用於 RxJS 5,這是 angular2 使用的。

我原以為您正在尋找Disposable上的 dispose 方法。

subscribe 方法返回一個 Disposable ( link )

我似乎無法在文檔中更明確地找到它,但這有效( jsbin ):

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

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

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

奇怪的是,取消訂閱似乎對你有用,而對我不起作用......

關於取消訂閱 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 中刪除以避免不必要的內存泄漏

我個人更喜歡使用 Subject 來關閉組件在銷毀生命周期步驟中可能具有的所有訂閱,這可以通過以下方式實現:

import { Component} from '@angular/core';
import { Subject } from "rxjs/Rx";

@Component({
  selector:    'some-class-app',
  templateUrl: './someClass.component.html',
  providers:   []
})

export class SomeClass {  

  private ngUnsubscribe: Subject<void> = new Subject<void>(); //This subject will tell every subscriptions to stop when the component is destroyed.

  //**********
  constructor() {}

  ngOnInit() {

    this.http.post( "SomeUrl.com", {}, null ).map( response => {

      console.log( "Yay." );

    }).takeUntil( this.ngUnsubscribe ).subscribe(); //This is where you tell the subscription to stop whenever the component will be destroyed.
  }

  ngOnDestroy() {

    //This is where we close any active subscription.
    this.ngUnsubscribe.next();
    this.ngUnsubscribe.complete();
  }
}

推薦的方法是使用 RxJS 運算符,例如takeUntil運算符。 以下是顯示如何使用它的代碼片段:-

import { Component, OnInit, OnDestroy } from '@angular/core';
import { interval, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html'
})
export class AppComponent implements OnInit, OnDestroy {
    private ngUnsubscribe = new Subject();

    constructor() { }

    ngOnInit() {
        var observable1 = interval(1000);
        var observable2 = interval(2000);

        observable1.pipe(takeUntil(this.ngUnsubscribe)).subscribe(x => console.log('observable1: ' + x));
        observable2.pipe(takeUntil(this.ngUnsubscribe)).subscribe(x => console.log('observable2: ' + x));
    }

    ngOnDestroy() {
        this.ngUnsubscribe.next();
        this.ngUnsubscribe.complete();
    }
}

您可以在此處找到該主題的詳細說明

if(mySubscription){
  mySubscription.unsubscribe();
}
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { SomeAPIService } from '../some_file/someAPIService.service.ts

@Component({
  templateUrl: './your_Page.html',
  styleUrls: ['./your_Styles.scss']
})

export class (your class) implements OnInit, OnDestroy {
   // This is a subject variable at it simplest form 
     private unsubscribe$ = new Subject<void>();

     constructor (private someAPIService : SomeAPIService) {}
   
     ngOnit(): void { 
       this.someAPIService.getTODOlist({id:1})
        .pipe(takeUntil(this.unsubscribe$))
         .subscribe((value: SomeVariable) => {
         // What ever value you need is SomeVariable
      },)
    }


     ngOnDestroy(): void {
    // clears all, page subscriptions 
      this.unsubscribe$.next();
      this.unsubscribe$.complete();
     }
`}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM