Rxjs를 사용하여 Angular에서 데이터를 캐싱하는 방법

10841 단어 rxjsangularjavascript
앱을 빌드할 때 메뉴 및 옵션과 같은 일부 데이터는 빈도에 따라 변경되지 않습니다. 사용자가 앱 주위를 이동할 때 서버에 대한 데이터가 속도와 사용자 경험에 다시 영향을 미치기 때문에 가장 좋은 방법은 캐시하는 것입니다.

Rxjs는 캐시를 구축하고 저장하는 쉬운 방법을 제공합니다. 두 연산자를 사용하면 매번 데이터를 가져오지 않고 계산을 피할 수 있습니다.

예시



나는 집과 주변의 두 가지 경로가 있는 간단한 앱을 가지고 있습니다. 홈에는 NBA 선수 목록이 표시됩니다. 또한 이름과 두 번째 이름을 사용하여 fullName을 빌드하여 데이터를 처리합니다.

사용자가 집을 떠나 돌아올 때마다 데이터를 가져와 프로세스를 수행해야 합니다. 계산과 같은 광범위한 과정이어야 합니다.

빈도에 따라 데이터가 변경되지 않는데 왜 데이터를 다시 가져옵니까? 캐싱을 할 때가 된 것 같습니다.

shareReplay 사용



우리는 앱의 성능과 응답을 개선하고 각 플레이어에 대해 fullName을 빌드하는 프로세스를 반복하지 않고 처리 시간을 볼 수 있는 프로세스 날짜를 갖습니다.

shareReplay는 앱의 데이터를 빠르게 캐시하고 새 구독자에게 데이터를 재생하는 데 도움이 됩니다.

Read more about shareReplay



데이터 흐름에 shareReplay 연산자를 추가하고 HTTP 요청에서 데이터를 가져온 다음 버퍼에 넣어 내 HTTP 요청의 마지막 방출을 재생할 수 있도록 합니다.

@Injectable()
export class NbaService {
  api = 'https://www.balldontlie.io/api/v1/';

  private teamUrl = this.api + 'players';
  public players$ = this.http.get<any[]>(this.teamUrl).pipe(
    map((value: any) => {
      return value?.data.map((player) => ({
        ...player,
        fullName: `${player.first_name} ${player.last_name}`,
        processed: new Date().toISOString(),
      }));
    }),
    shareReplay(1),
  );

  constructor(private http: HttpClient) {}
}


완벽합니다. 페이지에서 데이터를 볼 수 있습니다. 날짜 파이프 연산자를 사용하여 처리된 날짜의 형식을 더 잘 지정합니다.

<ul *ngIf="players$ | async as players">
  <li *ngFor="let player of players">
    {{ player.fullName }} {{ player.processed | date: 'medium' }}
  </li>
</ul>


한 페이지에서 다른 페이지로 앱을 탐색하고 홈 페이지로 돌아가면 캐시에서 데이터를 가져옵니다.

Chrome의 네트워크 탭에서 세부정보를 볼 수 있습니다.

https://stackblitz.com/edit/angular-ivy-3vql5l?file=src/app/nba.service.ts

예, 아주 쉽습니다. 앱에 캐시가 있습니다! 그러나 업데이트를 강제하는 방법은 무엇입니까?

캐시 업데이트 및 데이터 새로 고침



우리의 캐시는 매력처럼 작동하지만 때때로 사용자는 업데이트를 강제로 원합니다. 어떻게 할 수 있습니까? Rxjs 우리의 삶을 쉽게!

우리는 behaviorSubject를 사용하여 사용자가 데이터를 업데이트하려고 할 때 작업에 반응하는 데 도움을 줍니다.

먼저 동작 주체 유형 void와 새 메서드 updateData()를 만들어 작업을 내보내고 새 변수 apiRequest$를 만들어 HTTP 요청을 저장합니다.

우리의 players$ observable은 행동 주제에서 값을 가져오고 연산자 병합 맵을 사용하여 데이터를 파이프하여 HTTP 응답을 병합하고 observable을 반환하고 shareReplay를 추가합니다.

Read more about merge.



코드는 다음과 같습니다.

@Injectable()
export class NbaService {
  private _playersData$ = new BehaviorSubject<void>(undefined);
  api = 'https://www.balldontlie.io/api/v1/';

  private teamUrl = this.api + 'players';
  apiRequest$ = this.http.get<any[]>(this.teamUrl).pipe(
    map((value: any) => {
      console.log('getting data from server');
      return value?.data.map((player) => ({
        ...player,
        fullName: `${player.first_name} ${
          player.last_name
        } ${Date.now().toFixed()}`,
      }));
    })
  );

  public players$ = this._playersData$.pipe(
    mergeMap(() => this.apiRequest$),
    shareReplay(1)
  );

  constructor(private http: HttpClient) {}

  updateData() {
    this._playersData$.next();
  }
}


페이지에서 서비스 메서드를 호출하고 데이터 트리거 내 동작 주제를 강제로 업데이트하는 새 버튼을 만듭니다. stackbliz 예제에서 최종 버전으로 플레이할 수 있습니다.

완벽한! 여기에서 최종 코드를 볼 수 있습니다.
https://stackblitz.com/edit/angular-ivy-hbf6dc?file=src%2Fapp%2Fpages%2Fhome%2Fhome.component.css

요약



캐시를 생성하고 Rxjs를 사용하여 쉽게 강제 업데이트하므로 다음에 속도와 응답을 개선하고 싶을 때 쉽습니다!

의 몇 가지 비디오를 보는 것이 좋습니다. 그녀는 Rxjs에 대한 모든 것과 데이터 작업 방법을 매우 잘 설명합니다.




  • 사진 제공: Julia Zolotova on Unsplash

    좋은 웹페이지 즐겨찾기