Angular: Proper time to unsubscribe

后端 未结 3 650
清歌不尽
清歌不尽 2021-01-25 20:44

When using web services, when is the best time to unsubscribe? In my code I have been doing this

tempFunction() {
    const temp = this.myService.getById(id).sub         


        
相关标签:
3条回答
  • 2021-01-25 21:27

    The answer is: Unsubscribe when you are done with the subscription. If it needs to be active for the entire life of your component, then unsubscribing in ngOnDestroy is appropriate. If you only need one output from the observable, then unsubscribing in the .subscribe() callback makes sense. If some other condition in your app can mean the subscription is no longer needed at some arbitrary time, feel free to unsubscribe whenever needed.

    The only rule is "Don't forget to unsubscribe." There's no hard rule about when to do it.

    0 讨论(0)
  • 2021-01-25 21:28

    You don't need to unsubscribe from a simple web request like you have. They only fire once and will take care of the unsubscribe for you. Here is a SO question that discusses this very topic and why it is unnecessary.

    As a general topic of how to unsubscribe, the best approach tends to be using this pattern of using takeUntil. This allows you to ensure that everything is cleaned up when your component is destroyed in the cleanest way possible (without having to hold onto multiple subscriptions and calling unsubscribe on each of them).

    import { Subject } from 'rxjs/Subject';
    import 'rxjs/add/operator/takeUntil';
    
    @Component({ ... })
    export class ExampleComponent implements OnInit, OnDestroy {
        destroy$: Subject<boolean> = new Subject<boolean>();
    
        ngOnInit() {
            this.someMethodThatReturnsObservable(...)
                .takeUntil(this.destroy$)
                .subscribe(...);
    
            this.someOtherMethodThatReturnsObservable(...)
                .takeUntil(this.destroy$)
                .subscribe(...);
        }
    
        ngOnDestroy() {
            this.destroy$.next(true);
            // Now let's also unsubscribe from the subject itself:
            this.destroy$.unsubscribe();
        }
    }
    
    0 讨论(0)
  • 2021-01-25 21:30

    When you unsubscribe depends on what the subscription is and how you actually use it. In your example, you are calling .unsubscribe when the Observable completes. You don't need to do this since when the Observable has completed it will no longer emit. Instead you need to unsubscribe if the Observable will continue to emit after you may not need it anymore e.g. when navigating away from your component. That is why you see ngOnDestroy used for disposing of subscriptions.

    Generally you want to avoid calling .unsubscribe. See: https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87

    There are other ways to handle subscriptions such as using the take methods. Angular also has the very powerful async pipe that allows you to use Observables in templates and handles unsubscribing for you.

    Just to recap with some examples:

    // No need to unsubscribe here. Http Observables only emit once
    this.serviceUsingHttp.get().subscribe(useResponse);
    
    // Allows you to call `.unsubscribe` in case the subscription wasn't created properly
    events = new Subscription();
    ngOnInit() {
      this.events = fromEvent(document, 'someEvent').subscribe(useEvent);
    }
    ngOnDestroy() {
      this.events.unsubscribe();
    }
    
    destroyed$ = new Subject();
    ngOnInit() {
      fromEvent(document, 'resize').pipe(takeUntil(this.destroyed$)).subscribe(useResize);
      fromEvent(document, 'scroll').pipe(takeUntil(this.destroyed$)).subscribe(useScroll);
      fromEvent(document, 'change').pipe(takeUntil(this.destroyed$)).subscribe(useChange);
    }
    ngOnDestroy() {
      // Complete all of the event observables at once.
      this.destroyed$.next(true);
      this.destroyed$.complete();
    }
    
    0 讨论(0)
提交回复
热议问题