왜 setTimeout ()이 내 앱을 지연 시키지만 Rxjs timer (). subscribe (…)는 그렇지 않습니까?


9

100ms 간격으로 일부 주석을 "지연로드"하는 구성 요소가 있습니다.

setTimeout을 사용하면 실제로 게으 릅니다.

구성 요소

<div *ngFor="let post of posts">
   <app-post [post]="post" ></app-post>
</div>

이것은 내 응용 프로그램을 게으르게 만듭니다 (avg fps 14, 유휴 시간 51100ms) :

while(this.postService.hasPosts()){
  setTimeout(()=> {
   this.posts.push(this.postService.next(10));
  },100);
}

이것은 내 응용 프로그램을 부드럽게 만듭니다 (avg fps 35, 유휴 시간 40800ms)

while(this.postService.hasPosts()){
  timer(100).subscribe(()=> {
    this.posts.push(this.postService.next(10));
  });
}

왜 rxjs 타이머가 더 잘 작동하는지 설명이 있습니까?

firefox로 런타임 분석을 수행했습니다. 첫 번째 예에서는 프레임 속도가 14fps로 떨어집니다. 다른 예에서는 35fps입니다.

유휴 시간조차도 20 % 더 낮습니다.

이 방법은 훨씬 더 부드럽습니다 (avg fps 45, 유휴 시간 13500ms).

interval(100).pipe(takeWhile(this.postService.hasPosts()).subscribe(()=> {
    this.posts.push(this.postService.next(10));
  });
}

답변:


2

마지막 해결책은 유일한 것입니다.

다른 두 솔루션은 예상대로 작동하지 않아야합니다. 실제로 이것은 무한 루프가되어야합니다.

이것은 JavaScript의 이벤트 루프가 작동 하는 방식 때문입니다 . 다음 그림은 JavaScript 런타임 모델을 보여줍니다 (이미지는 여기 에서 가져옴 ).

여기에 이미지 설명을 입력하십시오

우리와 관련된 부분 stackqueue입니다. 자바 스크립트 런타임은queue . 각 메시지는 메시지가 처리 될 때 호출되는 함수와 연관됩니다.

스택의 경우, 각 함수 호출은 스택에 함수 인수와 로컬 변수를 포함하는 프레임을 만듭니다. 함수가 다른 함수를 호출하면 스택 위로 새 프레임이 푸시됩니다. 함수가 반환되면 최상위 프레임이 스택에서 튀어 나옵니다.

이제 스택이 비어 있으면 JavaScript 런타임은 queue가장 오래된 메시지에서 다음 메시지를 처리합니다 .

당신이 사용하는 경우 setTimeout(() => doSomething(),100)doSomething()기능은 100 밀리 초 후 대기열에 추가됩니다. 이것이 100 밀리 초가 보장 된 시간이 아니라 최소 시간 인 이유입니다. 따라서 doSomething method스택이 비어 있고 대기열에 다른 것이 없으면 유일한 호출됩니다.

그러나 while 루프에서 반복하고 조건이의 내부 코드에 따라 달라짐에 따라 setTimeout스택이 비어 있지 않으므로 this.posts.push(this.postService.next(10));코드가 호출 되지 않기 때문에 무한 루프를 만들었습니다 .

RxJS 구현의 경우에도 마찬가지입니다. 스케줄러를 사용하여 타이밍을 처리합니다. 이 RxJS 다른 내부 스케줄러 구현하지만, 우리가 구현에서 볼 수 있듯이 intervaltimer 우리는 스케줄러를 지정하지 않은 경우, 기본 하나는 asyncScheduler이다. asyncScheduler 스케줄 setIntervalsetTimeout위에서 언급 한대로 작동 하며 큐에 다른 메시지를 푸시합니다.

while 루프를 사용하여 두 가지 솔루션을 시도했지만 실제로 첫 번째 솔루션은 브라우저를 완전히 멈추고 두 번째 솔루션은 매우 게으르지 만 while 루프 내부의 콘솔에 무언가를 출력 할 수 있습니다. 나는 실제로 두 번째 것이 약간 더 성능이 좋은 이유를 모르겠지만 그럼에도 불구하고 둘 다 실제로 원하는 것이 아닙니다. 이미 좋은 해결책을 찾았으며이 답변이 첫 번째 해결책이 왜 그렇게 나쁜지를 이해하는 데 도움이되기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.