Angular, RxJS 및 페이지 가시성 API를 사용하여 사용자가 비활성 상태일 때 요청 중지/재시작

웹사이트나 앱에서 정해진 간격으로 새로운 데이터를 요청하는 것이 일반적입니다. 사용자가 더 이상 웹사이트나 앱을 보지 않는다면 어떻게 될까요? 브라우저를 최소화하거나 다른 탭이나 앱으로 전환하면 어떻게 되나요? Page Visibility API를 사용하여 네트워크 요청을 중지하고 다시 시작하는 방법을 알아봅시다!

설정



우리는 Quotable API에서 무작위 견적을 받는 서비스를 만들고 싶습니다. 서비스 내에서 사용할 몇 가지 항목을 가져와야 합니다. 지금 설정해 보겠습니다.

import { HttpClient } from '@angular/common/http';

import { BehaviorSubject, fromEvent, Observable, Subject, timer } from 'rxjs';
import { map, repeatWhen, switchMap, takeUntil, tap } from 'rxjs/operators';


Quote 의 모양에 대한 인터페이스를 정의해 보겠습니다.

interface Quote {
  _id: string;
  authorSlug: string;
  content: string;
  dateAdded: string;
  dateModified: string;
  length: number;
  tags: string[];
}


우리가 사용할 변수도 설정해 봅시다.

private readonly _restartTimer = new Subject<void>();
private readonly _stopTimer = new Subject<void>();

private readonly _randomQuote = new BehaviorSubject<Quote | null>(null);

readonly randomQuote$ = this._randomQuote.asObservable();


실제 견적을 표시하려면 async pipe을 사용하여 randomQuote$라는 observable을 구독할 수 있습니다.

<blockquote *ngIf="randomQuote$ | async as randomQuote">
  {{ randomQuote.content }}
</blockquote>


임의 견적 받기



HttpClient을 사용하여 Quotable API에 HTTP 요청을 하려고 합니다. 서비스 생성자 내에서 다음을 전달합니다.

constructor(private http: HttpClient) {}


이제 getRandomQuote라는 함수를 만들어 보겠습니다. Quotable API에 GET 요청을 하고 무작위 견적을 반환합니다. 반환된 견적은 randomQuote BehaviorSubject로 전달됩니다.

private getRandomQuote(): Observable<Quote> {
  return this.http.get<Quote>('https://api.quotable.io/random').pipe(
    tap(quote => this._randomQuote.next(quote))
  );
}


매분마다 무작위 견적 받기



이제 무작위 견적을 받을 수 있으므로 1분에 하나씩 받아보도록 하겠습니다! RxJStimer 함수가 매분 실행되고 RxJSswitchMap 연산자가 1분이 지난 후 임의 인용을 가져오는 관찰 가능 항목으로 전환해야 합니다.

createTimer라는 함수를 만듭니다. 그것은 타이머를 생성하고 매분마다 임의의 견적을 얻을 것입니다. 시간은 밀리초 단위이므로 60,000밀리초는 1분입니다.

private createTimer(): void {
  timer(0, 60000).pipe(
    switchMap(() => this.getRandomQuote())
  ).subscribe();
}


정지/재시작 타이머



타이머를 중지했다가 다시 시작하는 방법이 필요합니다. restartTimer 및 stopTimer라는 두 가지 함수를 만들어 보겠습니다. 둘 다 각각의 주제에서 다음을 호출하여 작업을 트리거합니다.

private restartTimer(): void {
  this._restartTimer.next();
}

private stopTimer(): void {
  this._stopTimer.next();
}


이제 createTimer 함수를 업데이트하고 연산자를 몇 개 더 추가해 보겠습니다. takeUntil 연산자는 트리거할 stopTimer Subject를 수신합니다. 트리거되면 타이머가 중지됩니다. repeatWhen 연산자는 트리거할 restartTimer Subject를 수신합니다. 트리거되면 타이머를 다시 시작합니다.

private createTimer(): void {
  timer(0, 60000).pipe(
    takeUntil(this._stopTimer),
    repeatWhen(() => this._restartTimer),
    switchMap(() => this.getRandomQuote())
  ).subscribe();
}


페이지 가시성 API



우리는 매분 임의의 인용문을 받고 있지만 사용자가 더 이상 우리 웹사이트나 앱을 보지 않는다면 어떻게 될까요? 브라우저를 최소화하거나 다른 탭이나 앱으로 전환하면 어떻게 되나요? 사용자가 돌아올 때까지 매분마다 임의의 인용문을 받지 않도록 합시다.

들을 수 있는 visibilitychange이라는 유용한 이벤트가 있습니다. 페이지 콘텐츠가 사용자에게 표시되는지 또는 숨겨지는지 여부를 알려주는 visibilityState 속성을 제공합니다.

가시성 변경 이벤트를 수신할 onVisibilityChange라는 함수를 만듭니다. 가시성 상태가 표시되면 타이머를 다시 시작할 수 있습니다. 그렇지 않으면 타이머를 중지하십시오.

private onVisibilityChange(): void {
  fromEvent(document, 'visibilitychange').pipe(
    tap((event: Event) => {
      const state = (event.target as Document).visibilityState;

     if (state === 'visible') {
        this.restartTimer();
      } else {
        this.stopTimer();
      }
    })
  ).subscribe();
}


남은 일은 생성자에서 createTimer 및 onVisibilityChange 함수를 호출하는 것입니다.

constructor(private http: HttpClient) {
  this.createTimer();
  this.onVisibilityChange();
}


사용자가 웹사이트나 앱을 적극적으로 사용하지 않을 때 서버 리소스를 절약한 것을 축하합니다!


저희 웹사이트 https://nightwolf.dev를 방문하고 Facebook 및 !

좋은 웹페이지 즐겨찾기