Programing

RxJS 6 페이지가 활성화되지 않은 경우 일시 중지 또는 버퍼 관찰 가능

c10106 2022. 3. 14. 21:14
반응형

RxJS 6 페이지가 활성화되지 않은 경우 일시 중지 또는 버퍼 관찰 가능

그래서 나는, 편지라고 하자, 그리고 그것들을 한 단어로 합치려면 모든 글자들이 올바른 순서대로 필요해.사용자가 탭을 변경하거나 브라우저 또는 스위치 응용 프로그램을 최소화하기 전까지 모든 것이 정상적으로 작동함 - 동작은 내가 사용하는 것과 거의 동일함setTimeout()-주문, 분실물 등 엉망진창나는 나의 목표를 이루기 위해 노력했다.bufferWhen(),bufferToggle(),takeUntil(),publish()그리고connect()그러나 아무것도 성공하지 못했다.나는 사용할 것을 고려했다.delayWhen또한, 하지만 그것은 더 이상 사용되지 않고 아마도 하천을 즉시 멈추기 때문에 적절하지 않을 것이다.어떤 기능을 어떻게 사용해야 할까?내 암호는 다음과 같다.

export class MyComponent implements AfterViewInit {
  private visibilityChange$ = fromEvent(document, 'visibilitychange').pipe(startWith('visible'), shareReplay({ refCount: true, bufferSize: 1 }));
  private show$ = this.visibilityChange$.pipe(filter(() => document.visibilityState === 'visible'));
  private hide$ = this.visibilityChange$.pipe(filter(() => document.visibilityState === 'hidden'));

  public ngAfterViewInit() {
    const lettersStream$ = zip( // add delay for each letter
            from(['w', 'o', 'r', 'd']),
            interval(1000))
           // pause when hide$ fires, resume when show$
          .pipe(map(([letter, delayTime]) => letter))
          .subscribe(console.log);
  }
}

나는 스택블리츠에 대한 데모를 만들었다. 내가 원하는 것은 단지 화면에 문구가 어떻게 쓰여지는지를 보는 것이다.

내가 RxJS 스네이크 게임에서 비슷한 일시중지/일시정지 작업을 했으니, 너의 예를 들어줄게.

아이디어는 다음을 갖는 것이다.interval(1000)진실의 근원으로서, 모든 것이 진리의 근원이 될 것이라는 것을 의미한다.그래서 우리의 목표는 가시성에 대한 사건 발생을 멈추고 가시성 쇼를 계속해야 한다는 사실에 기초하여 이 간격을 일시 중지하는 것이 된다.마지막으로, 우리는 가시성 숨김에 대한 소스 간격 듣기를 멈추고 가시성 쇼가 도착하면 다시 듣기 시작할 수 있다.이제 정확한 구현으로 이동하십시오.

수정된 StackBlitz 데모 코드도 RxJS Pause Observable에서 재생할 수 있다.

import { of, interval, fromEvent, timer, from, zip, never } from 'rxjs';
import { delayWhen, tap, withLatestFrom, concatMap, take, startWith, distinctUntilChanged, switchMap, shareReplay, filter, map, finalize } from 'rxjs/operators';

console.log('-------------------------------------- STARTING ----------------------------')

class MyComponent {
  private visibilityChange$ = fromEvent(document, 'visibilitychange')
    .pipe(
      map(x => document.visibilityState),
      startWith('visible'),
      shareReplay(1)
    );

  private isVisible$ = this.visibilityChange$.pipe(
    map(x => x === 'visible'),
    distinctUntilChanged(),
  );

  constructor() {
    const intervalTime = 1000;
    const source$ = from('word or two'.split(''));
    /** should remove these .pipe(
        concatMap(ch => interval(intervalTime).pipe(map(_ => ch), take(1)))
      );*/

    const pausableInterval$ = this.isVisible$.pipe(
      switchMap(visible => visible ? interval(intervalTime) : never()),
    )

    const lettersStream$ = zip(pausableInterval$, source$).pipe(
      map(([tick, letter]) => letter),
    ).subscribe(letter => {
      this.writeLetter(letter);
    });
  }

  private writeLetter(letter: string) {
    if (letter === ' ') letter = '\u00A0'; // fix for spaces
    document.body.innerText += letter;
  }
}

const component = new MyComponent();

이건 StackBlitz의 정확한 코드야. 내가 더 잘 설명하려고 복사한 거야.

이제 여러분을 위해 흥미로운 부분들을 설명해 봅시다.

  1. 을 보아라visibilityChange$그리고isVisible$약간 변형되어서 첫 번째 것은 끈 값을 내보낸다.'visible'또는'hidden'에 기반을 둔document.visibilityState두번째는 진실이다.document.visibilityState대등하다'visible'.

  2. 을 보아라source$편지를 내보내고 나서 의 도움으로 1초간 기다릴 것이다.concatMap그리고interval와 함께take(1)그리고 텍스트에 문자가 남지 않을 때까지 이 과정을 수행한다.

  3. 봐봐pausableInterval$. 기준this.isVisible$에 따라 달라질 것document.visibilityState, 우리의pausableInterval$초당 에미팅 아이템이 되거나, 에미레이트 항공으로 인해 어떤 것도 배출하지 않을 것이다.never().

  4. 마지막으로 한 번 보십시오.lettersStream$. 의 도움으로zip(), 우리는 지퍼를 채울 것이다.pausableInterval$그리고source$그래서 우리는 소스에서 한 글자를 얻을 것이고, 사용 가능한 간격에서 한 틱을 얻을 수 있다.만약pausableInterval$가시성 변화로 인해 방출이 중단되고, zip도 대기할 것이다. 두 관측기기가 함께 방출되어야 구독자에게 이벤트를 보낼 수 있기 때문이다.

사용 사례에 대해 약간 혼란스럽지만, 이렇게 하면 해결된다.

대신 먼저 다음 작업을 수행하십시오.

private isVisible$ = this.visibilityChange$.pipe(
                       filter(() => document.visibilityState === 'visible'), 
                       distinctUntilChanged()); // just a safety operator

다음 작업을 수행하십시오.

const lettersStream$ = this.isVisible$.pipe(
        switchMap((isVisible) => (isVisible)
          ? zip( // add delay for each letter
              from(['w', 'o', 'r', 'd']),
              interval(1000))
            .pipe(map(([letter, delayTime]) => letter))
          : NEVER
        )
      ).subscribe(console.log);

가시성이 변경될 때마다 switchMap, 표시되는 경우 소스 구독, 그렇지 않으면 아무 것도 수행하지 마십시오.

이조작된 예와 함께,그 동작은 약간엉뚱할 것이다.왜냐하면 fromproperties는 항상 동일한 시퀀스를 방출하지만 실제 비 정적 소스를 가지고는 의도한 대로 작동해야 하기 때문이다.

참조URL: https://stackoverflow.com/questions/57020431/rxjs-6-pause-or-buffer-observable-when-the-page-is-not-active

반응형