2015-01-11 5 views
4

Rx로 만든 사용자 정의 된 관찰 가능 객체를 사용하여 관찰자가 작업을 완료했는지 여부를 감지하는 방법을 찾고 싶습니다. Observable.create. 사용자 정의 된 관찰 가능 객체가이를 종료하고 올바르게 정리할 수 있습니다. RxJs - observer.isStopped, observer.observer.isSpped 및 observed.m.isDisposed 사이의 차이점

그래서 나는 필드의 종류가이 목적을 위해 관찰자 객체에 사용할 수있는 알아 내기 위해 다음과 같이 몇 가지 테스트 코드를 만들었습니다.

var Rx = require("rx") 

var source = Rx.Observable.create(function (observer) { 

    var i = 0; 
    setInterval(function(){ 
    observer.onNext(i); 
    console.dir(observer); 
    i+=1 
    }, 1000) 

}); 

var subscription = source.take(2).subscribe(
    function (x) { console.log('onNext: %s', x); } 
); 

출력은 다음과 같습니다

onNext: 0 
{ isStopped: false, 
    observer: 
    { isStopped: false, 
    _onNext: [Function], 
    _onError: [Function], 
    _onCompleted: [Function] }, 
    m: { isDisposed: false, current: { dispose: [Function] } } } 
onNext: 1 
onCompleted 
{ isStopped: true, 
    observer: 
    { isStopped: false, 
    _onNext: [Function], 
    _onError: [Function], 
    _onCompleted: [Function] }, 
    m: { isDisposed: true, current: null } } 

이 목표, 즉, observer.isStopped, observer.observer.isStopped withmy 할 수있는 뭔가를 갖고있는 것 같다 관찰자 객체 3 개 필드가 보인다 observer.m.isDiposed.

은 내가 선택해야 그들이 모두에 대해 그리고 어느 궁금 해서요.

============================================== ==================================== 내 질문에 대한 동기

Andre의 제안에 따라 시나리오를 추가합니다. 내 질문에 동기를 부여했다. 내 응용 프로그램에서

, 나는 window.requestAnimationFrame (콜백) 메커니즘을 기반으로 몇 가지 UI 애니메이션을하려고했다. requestAnimationFrame은 브라우저 렌더 엔진에서 결정한 시간 내에 제공된 콜백을 호출합니다. 콜백 일부 애니메이션 스텝을 재귀 적 애니메이션이 끝날 때까지 다시 requestAnimationFrame를 호출 할 예정이다.

나는 추상화 아래로 관찰이 메커니즘을합니다.

function animationFrameRenderingEventsObservable(){ 
    return Rx.Observable.create(function(subscriber){ 
     var fn = function(frameTimestmpInMs){ 
      subscriber.onNext(frameTimestmpInMs); 
      window.requestAnimationFrame(fn) 
     }; 
     window.requestAnimationFrameb(fn); 
    }); 
} 

그런 다음 애니메이션이 필요한 곳에서도 사용할 수 있습니다. 하나의 예를 들어, 내가 구독을 종료

animationFrameRenderingEventsObservable() 
    .takeUntil(touchStartEventObservable) 
    .subscribe(animationFunc) 

그러나, 나는 takeUntil (touchStartEventObservable) 후 animationFrameRenderingEventsObservable에서 무한 재귀를 중지하는 방법이 필요합니다 이동 화면을 터치 사용자 UNTIL 약간의 애니메이션을 그릴 필요가있다. 예상대로

따라서, 나는 내 테스트에 따르면

function animationFrameRenderingEventsObservable(){ 
    return Rx.Observable.create(function(subscriber){ 
     var fn = function(frameTimestmpInMs){ 
      if (!subscriber.isStopped){ 
       subscriber.onNext(frameTimestmpInMs); 
       window.requestAnimationFrame(fn) 
      }else{ 
       subscriber.onCompleted(); 
      } 
     }; 
     window.requestAnimationFrameb(fn); 
    }); 
} 

에 animationFrameRenderingEventsObservable를 수정, 코드가 작동합니다. 그러나 Andre가 말했듯이 subscriber.isStopped를 사용하거나 비슷하게 올바른 방법이 아니라면 올바른 방법은 무엇입니까?

답변

2

create에 제공하는 기능에서 관찰자가 관찰 대상을 구독 취소 할 때 호출 할 정리 기능을 반환 할 수 있습니다. 애니메이션 프레임 요청을 중지시키는 함수를 제공해야합니다.

Rx.Observable.animationFrames = function() { 
    /// <summary> 
    /// Returns an observable that triggers on every animation frame (see https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame). 
    /// The value that comes through the observable is the time(ms) since the previous frame (or the time since the subscribe call for the first frame) 
    /// </summary> 
    var request = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame, 
     cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || 
      window.msCancelAnimationFrame || window.msCancelRequestAnimationFrame; 

    return Rx.Observable.create(function (observer) { 
     var requestId, 
      startTime = window.mozAnimationStartTime || Date.now(), 
      callback = function (currentTime) { 
       // If we have not been disposed, then request the next frame 
       if (requestId !== undefined) { 
        requestId = request(callback); 
       } 

       observer.onNext(Math.max(0, currentTime - startTime)); 
       startTime = currentTime; 
      }; 

     requestId = request(callback); 

     return function() { 
      if (requestId !== undefined) { 
       var r = requestId; 
       requestId = undefined; 
       cancel(r); 
      } 
     }; 
    }); 
}; 

사용법 : 여기 당신은 내가 몇 년 전에 쓴 원하는 것을 그 작업 관찰의

Rx.Observable.animationFrames().take(5).subscribe(function (msSinceLastFrame) { ... }); 
0

observer.is를 사용하는 경우 문제가 발생합니다. 이들은 API 함수가 아니며 구현 세부 사항입니다.

내가 Rx.Observable.create로 만든, 사용자 정의 관찰을 사용하여 관찰자가 완료 여부를 감지 할 수있는 방법을 찾으려면 같은 사용자 정의 관찰은 종료하고 일부는 제대로 청소를 할 수있는 .

'oncompleted'가 발생하면 관찰자가 정리를합니다. Observable에서.위에서 생성 한 경우 사용자 지정 관찰 가능 항목이 종료 된 것으로 간주 할 때 observer.onCompleted()으로 호출해야하며 사용자 지정 관찰 가능 항목이 무한대이면 observer.onCompleted()을 호출하지 않아야합니다. 또한 try/catch를 사용하여 Observable.create 내에 전체 코드를 래핑하고 catch에 observer.onError(err)을 호출해야합니다.

관찰자가 "관찰 가능 항목 사용을 끝냈다"때 관찰 대상을 "정리"하려고한다면 잘못하고있는 것입니다. 본질적으로, 관측 대상이 관측 대상에 반응해야하는 경우 관측 대상이 관측 가능해야 함을 의미합니다. 아마도 Observable.create가이를위한 도구가 아닙니다.

특정 작업을 수행하는 대신 수행하려는 작업을 더 잘 전달하십시오.

UPDATE : 당신이 원하는 애니메이션을 기반으로

: RxJS의 맥락에서이 requestAnimationFrame은 스케줄러가 아닌 관찰 할. Use it from the RxJS-DOM library.

+0

앙드레을, 나는 나의 의욕을 설명 할 수있는 시나리오를 포함하는 내 질문에 업데이트되었습니다. – xwk

+0

답변을 업데이트했습니다 –

+1

- 기본적으로 관찰 관찰자가 관찰 관찰자에게 반응해야하는 경우 관찰자가 관찰 가능이어야 함을 의미합니다 * NOT TRUE * Rx는 관찰자와 관찰자 간의 통신 채널을 두 개의 특정 이벤트에 대해 다시 설정합니다. 관찰자가 * 구독 할 때 관찰 가능이 통지되고, 관찰자가 구독을 취소 할 때 관찰자에게 통지됩니다. 추위와 뜨거운 관측을 가능하게하는 것은이 메커니즘이며, 근본적으로 아무도보고 있지 않으면 자원을 소비하지 않는 게으른 관찰 가능 요소입니다. – Brandon