2014-04-22 6 views
5

RxJS를 사용하여 sync world와 비동기적인 이벤트 세계를 "연결"하고 싶습니다. 특히 시간 간격 동안 수집 된 이벤트 배열을 반환하는 함수를 만들고 싶습니다. 내가Array에 관찰 가능한 RxJS 수집

var source = Rx.Observable 
.interval(100 /* ms */) 
.bufferWithTime(1000).take(1) 

내가 잘 올바른 값을 인쇄 할 수 있습니다 원하는 것을하는 관찰 가능한 만들 수 있습니다

var subscription = source.subscribe(
    function (x) { 
     console.log('Next: ' + JSON.stringify(x)); 
    }, 
    function() { 
     console.log('Completed'); 
    }); 

이 내가 원하는 할당하는 것입니다

[0,1,2,3,4,5,6,7,8] 
Completed 

를 인쇄하지만 원하는 이 배열을 변수로. 개념적으로 나는

var collectedDuringSecond = source.toPromise.getValue()

아이디어 같은 위의 라인이 collectedDuringSecond이 포함됩니다 완료된 후 getValue 그렇게 차단하는 것입니다 원하는 [0,1,2,3,4,5,6,7,8]

+1

먼저 JavaScript로 차단하는 것이 가장 좋은 방법은 아닙니다. Rx를 사용하면 특히 비동기 프로그래밍에서 발생하는 많은 고통을 피할 수 있으므로 가치를 확보하기 위해 차단해야하는 이유는 무엇입니까? –

+0

저는 JavaScript가 처음이므로 차단을 원하지 않을 수도 있습니다.). 기본적으로이 특정 데이터 세트는 이벤트를 전달 메커니즘으로 사용하는 경우에도 상당히 정적입니다. 따라서 "더 간단한"동기식 API를 API 클라이언트에 노출하고자했습니다. 귀하의 의견을 바탕으로 아마도 재검토하고 Observable을 반환하고 클라이언트가 원하는 방식으로 이벤트를 사용하게해야합니다. – apolenur

+0

확실히 좋은 접근 방법입니다. * 어떤 이유로 (왜 그런지 모르겠다.) Rx를 숨기고 싶다면, 당신은 API에 노드 스타일의 콜백 ('function (err, value) {...}')을 제공 할 수있다. 주목할 만한. 그러나 API 호출 자체에서 콜백을 제공하는 대신 Observable을 공용 API의 일부로 공개하는 것이 좋습니다. 왜냐하면 Observable은 항상 객체에 "구독"할 수 있기 때문입니다. –

답변

6

JavaScript의 동기 이벤트 프로그래밍은 매우 제한적입니다. 사실, 많은 경우에 불가능할 수도 있습니다. Rx 소스를 수정하지 않고 동기식 인터페이스를 제공 할 수 있는지 확인하기 위해 Rx로 해킹을 시도했다. (좋은 이유로) 스트레이트 자바 스크립트에서는 불가능하다.

Observable을 API의 일부로 노출시키고 소비자가 거기에서 처리 할 수있게하는 것이 좋습니다 (물론 Rx를 사용하도록 미세 조정이 필요함).

function MyClass() { 

    this.getArrayOfStuffAsObservable = function() { 
     return Rx.Observable.interval(100) 
      .bufferWithTime(1000).take(1); 
    }; 

    // this is optional and I don't recommend it, since you already have Rx available. 
    // additionally, consumers will probably miss the fact that you can dispose 
    // of the subscription. 
    this.getArrayOfStuff = function (callback) { 
     var value; 
     return this.getArrayOfStuffAsObservable() 
      .subscribe(
       function (x) { 
        value = x; 
       }, 
       function (err) { 
        callback(err); 
       }, 
       function() { 
        if (hasValue) { 
         callback(undefined, value); 
        } else { 
         callback('did not receive value'); 
        } 
       }); 

    }; 
}; 

추가 참고로, 당신은 같은 일을하고 정말 두 가지 방법이다 (이 특정 예를 들어 take 대신 bufferWithTime와 함께 toArray을 사용할 수 있지만, 하나는 시간과 기반으로 기타 항목 수에 따라). toArray은 기본 관찰 자료의 모든 값을 수집하는 Observable을 작성하고 기본 Observable이 완료 될 때 해당 값을 배열로 제공합니다.

this.getArrayOfStuffAsObservable = function() { 
    return Rx.Observable.interval(100) 
     .take(10) 
     .toArray(); 
}; 
관련 문제