앙겔의 엥겔데스트로를 깊이 연구하다

이 글은 내가 이번 주 일찌감치 발표한 각도 있는 핫한 추문의 연장선상이다.그것은 널리 환영을 받았고 상당히 큰 토론을 불러일으켰다.이 문서에서 다루는 개념은 이러한 논의를 반영하므로 검토에 시간이 좀 걸릴 수 있습니다.
액체 오류: 내부 오류
상술한 추문의 확장으로 우리는 ngOnDestroy의 제한을 어떻게 그리고 언제 호출할지 토론할 것이다.우리는 또 이러한 제한을 극복하는 방법을 토론할 것이다.Angular 또는 Angular의 라이프 사이클 방법에 익숙하지 않은 경우 official docs here을 확인하는 것이 좋습니다.

NPM 패키지 버전


이 문서는 컨텍스트에서 다음 npm package.json 버전을 사용하고 있다고 가정합니다.
  • @angular/* : 7.2.9
  • 엥겔데스트로 안내


    깊이 파헤치기 전에 ngOnDestroy을 몇 분 동안 돌아봅시다.
    Ngondestory는 클래스에서 OnDestroy을 실현하고 ngOnDestroy이라는 새로운 클래스를 추가하는 라이프 사이클 방법이다.Angular Docs에 따르면 주요 용도는 "Angular가 명령/구성 요소를 폐기하기 전에 청소하는 것입니다. 구독 대상을 취소하고 이벤트 처리 프로그램을 분리하여 메모리 유출을 피합니다. Angular가 명령/구성 요소를 폐기하기 전에 호출합니다."

    누수 부품


    만약에 우리가 MyValueComponent이라는 구성 요소가 있다면 MyService 방법에서 ngOnInit의 값을 구독했다.
    import { Component, OnInit } from '@angular/core';
    import { MyService } from './my.service';
    
    @Component({
      selector: 'app-my-value',
      templateUrl: './my-value.component.html',
      styleUrls: [ './my-value.component.css' ]
    })
    export class MyValueComponent implements OnInit {
      myValue: string;
    
      constructor(private myService: MyService) {}
    
      ngOnInit() {
          this.myService.getValue().subscribe(value => this.myValue = value);
      }
    }
    
    Angular 애플리케이션의 수명 주기 동안 이 구성 요소를 여러 번 생성하고 제거하면 ngOnInit이 생성될 때마다 새 구독이 생성됩니다.우리의 가치가 지수급으로 갱신됨에 따라, 이것은 곧 통제력을 잃을 수도 있다.이것은 이른바 메모리 유출을 야기했다.메모리 유출은 응용 프로그램의 성능에 심각한 손상을 초래할 뿐만 아니라 예측할 수 없거나 의외의 행위도 증가시킬 수 있다.이 빈틈을 어떻게 막는지 계속해서 읽어 봅시다.

    MyValueComponent에서 취약점 수정


    메모리 유출을 복구하기 위해서, 우리는 구독 중인 OnDestroyunsubscribe을 사용하여 구성 요소 종류를 확충해야 한다.구성 요소를 업데이트하고 다음을 추가합니다.
  • 유형 스크립트에 OnDestroy 추가
  • importOnDestroy 목록
  • 에 추가
  • 구독 추적을 위한 implements이라는 클래스 필드를 만듭니다
  • 에서 myValueSub: Subscriptionthis.myValueSub과 같은 값으로 설정
  • 에서 this.myService.getValue().subscription이라는 새로운 방법을 만듭니다
  • 가입이 설정되어 있으면 ngOnDestroy 이내에 this.myValueSub.unsubscribe()으로 전화하십시오.
  • 업데이트된 어셈블리는 다음과 같습니다.
    import { Component, OnInit, OnDestroy } from '@angular/core';
    import { MyService } from './my.service';
    
    @Component({
      selector: 'app-my-value',
      templateUrl: './my-value.component.html',
      styleUrls: [ './my-value.component.css' ]
    })
    export class MyValueComponent implements OnInit, OnDestroy {
      myValue: string;
      myValueSub: Subscription;
    
      constructor(private myService: MyService) {}
    
      ngOnInit() {
          this.myValueSub = this.myService.getValue().subscribe(value => this.myValue = value);
      }
    
      ngOnDestroy() {
        if (this.myValueSub) {
            this.myValueSub.unsubscribe();
        }
      }
    }
    

    메모리 유출 초과


    위대하다현재 당신은 ngOnDestroy의 배경 지식과 메모리 유출을 제거하는 것이 이 생명주기 방법의 주요 용례입니다.하지만 더 나아가 추가 정리 논리를 늘리고 싶다면?서버에서 전화를 정리하는 게 어때요?아마도 사용자의 내비게이션을 막을 수 있습니까?
    계속해서 읽어 보시면 최상의 사용을 위해 ngOnDestroy을 업그레이드하는 세 가지 방법에 대해 살펴보겠습니다.

    업그레이드 #1 - Ngondestory 비동기식


    Angular의 다른 라이프 사이클 방법과 마찬가지로 ngOnDestroy을 사용하여 ngOnDestroy을 수정할 수 있습니다.이것은 async으로 돌아가는 방법을 호출할 수 있도록 합니다.이것은 관리 프로그램에서 활동을 정리하는 강력한 방법이다.네가 계속 책을 읽을 때, 우리는 이 방면의 예를 탐구할 것이다.

    AuthService를 호출할 로직을 추가합니다.Ngondestory에서 로그아웃

    Promise이 제거되면 서버측 로그아웃을 수행해야 한다고 가정해 보겠습니다.이를 위해 다음과 같이 방법을 업데이트합니다.
  • MyValueComponentAuthService에 추가
  • importsAuthService에 추가
  • 방법명 constructor 앞에 async 추가
  • 키워드를 사용하여 ngOnDestroy - AuthService으로 전화하십시오.
  • 업데이트된 logout은 다음과 같습니다.
    import { Component, OnInit, OnDestroy } from '@angular/core';
    import { MyService } from './my.service';
    import { AuthService } from './auth.service';
    
    @Component({
      selector: 'app-my-value',
      templateUrl: './my-value.component.html',
      styleUrls: [ './my-value.component.css' ]
    })
    export class MyValueComponent implements OnInit, OnDestroy {
      myValue: string;
      myValueSub: Subscription;
    
      constructor(private myService: MyService, private authService: AuthService) {}
    
      ngOnInit() {
          this.myValueSub = this.myService.getValue().subscribe(value => this.myValue = value);
      }
    
      async ngOnDestroy() {
        if (this.myValueSub) {
            this.myValueSub.unsubscribe();
        }
    
        await this.authService.logout();
      }
    }
    
    타다!이제 구성 요소가 제거되면 사용자가 로그아웃되고 서버에서 세션이 제거되는 await 호출이 실행됩니다.

    업그레이드 #2 - 브라우저 이벤트 중 실행


    많은 개발자들은 MyValueComponent이 실행 중인 브라우저 세션의 상하문에서 삭제될 때만 터치되는 것을 놀라게 발견했다.
    다시 말하면 다음과 같은 상황에서 async은 신뢰할 수 없는 호출이다.
  • 페이지 새로 고침
  • 탭 닫기
  • 브라우저 닫기
  • 페이지 떨어진 내비게이션
    이전의 예시를 고려하면 사용자가destroy에서 로그아웃하면 거래를 파괴할 수 있습니다.왜?대부분의 사용자는 브라우저 세션을 닫거나 다른 사이트로 이동하기만 하면 됩니다.그렇다면 ngOnDestroy이 이 장면에서 작용하지 않는다면 우리는 어떻게 이 이벤트에 포획되거나 연결될 수 있습니까?

    HostListener로 Ngondestry를 꾸며줍니다.


    TypeScript decorators are used throughout Angular applications. More information can be found here in the official TypeScript docs.


    상기 브라우저 이벤트에서 ngOnDestroy을 실행하도록 하기 위해서, 우리는 ngOnDestroy의 맨 위에 간단한 코드를 추가할 수 있습니다.앞의 ngOnDestroy 예를 살펴보고 ngOnDestroy을 장식해 보겠습니다.
  • MyValueComponentngOnDestroy에 추가
  • HostListenerimports 상단에 배치
  • 업데이트된 @HostListener('window:beforeunload')은 다음과 같습니다.
    import { Component, OnInit, OnDestroy, HostListener } from '@angular/core';
    import { MyService } from './my.service';
    import { AuthService } from './auth.service';
    
    @Component({
      selector: 'app-my-value',
      templateUrl: './my-value.component.html',
      styleUrls: [ './my-value.component.css' ]
    })
    export class MyValueComponent implements OnInit, OnDestroy {
      myValue: string;
      myValueSub: Subscription;
    
      constructor(private myService: MyService, private authService: AuthService) {}
    
      ngOnInit() {
          this.myValueSub = this.myService.getValue().subscribe(value => this.myValue = value);
      }
    
      @HostListener('window:beforeunload')
      async ngOnDestroy() {
        if (this.myValueSub) {
            this.myValueSub.unsubscribe();
        }
    
        await this.authService.logout();
      }
    }
    
    현재, 구성 요소가 Angular에 의해 파괴되었을 때, 브라우저 이벤트 ngOnDestroy이 터치되었을 때, MyValueComponent 방법을 사용합니다.이것은 강력한 조합이다!

    HostListener에 대한 자세한 내용

    ngOnDestroy은 각도 장식기로서 어떤 방법의 꼭대기에 놓을 수 있다.이 장식기는 window:beforeunload과 선택할 수 있는 @HostListener()의 두 가지 파라미터를 받아들인다.위의 예에서는 eventName을 DOM 이벤트로 전달했습니다.이것은 DOM 이벤트 args을 트리거할 때 Angular에서 자동으로 우리의 방법을 호출한다는 것을 의미합니다.window:beforeunload에 대한 자세한 내용은 official docs을 참조하십시오.
    이 옵션을 사용하여 페이지 또는 구성 요소의 탐색을 방지하려면 다음과 같이 하십시오.
  • window:beforeunload@HostListener 매개변수
  • 에 추가
  • $event으로 전화 연결
  • @HostListener을 브라우저에
  • 의 메시지를 표시할 문자열 값으로 설정합니다.
    다음 예는 다음과 같습니다.
    @HostListener('window:beforeunload', ['$event'])
    async ngOnDestroy($event) {
      if (this.myValueSub) {
        this.myValueSub.unsubscribe();
      }
    
      await this.authService.logout();
    
      $event.preventDefault();
      $event.returnValue = 'A message.';
    }
    

    PLEASE NOTE: This is not officially supported by Angular! OnDestroy and ngOnDestroy suggest that there is no input argument on ngOnDestroy allowed. While unsupported, it does in fact still function as normal.


    Windows에 대한 자세한 내용: 제거 전

    event.preventDefault()event.returnValue을 마운트 해제하기 전에 발생한 이벤트입니다.자세한 내용은 https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event 문서를 참조하십시오.
    주의해야 할 사항:
  • 은 iOS Safari를 제외한 현재 모든 주요 브라우저에서 이 이벤트를 지원합니다.
  • iOS Safari에서 이 기능이 필요한 경우 Stack Overflow thread을 검토하십시오.
  • 이 이벤트를 사용하여 내비게이션을 막으려면 window:beforeunload을 표시할 메시지 문자열로 설정해야 합니다.자세한 내용은 example을 참조하십시오.
  • 결론


    나는 본문에서 추천한 몇 가지 기교가 주류가 아니어서 약간의 우려를 불러일으킬 수 있다는 것을 깨달았다.응용 프로그램에서 하는 일에 적합한지 확인하기 위해 예전과 같이 시도해 보세요.만약 그들이 일을 잘한다면!없으면 계속하세요.
    만약 어떤 의견이나 문제가 있으면 언제든지 저에게 연락 주십시오

    추가 자원


    나는 네가 궁극적인 각도 과정에 참가할 것을 강력히 건의한다.이것은 매우 가치 있는 돈이다. 나는 그것을 교육 도구로 삼아 새로운 개발자와 경험이 있는 개발자를 위해 사용한다.아래 링크를 클릭하여 등록하세요.
    Ultimate Courses: Expert online courses in JavaScript, Angular, NGRX and TypeScript

    좋은 웹페이지 즐겨찾기