2016-09-30 2 views
4

API에서받은 응답을 기반으로 API 호출을 계속 수행 할 수있는 방법을 찾기 위해 Rx.js repeat 설명서를 읽었습니다. 한 번에 2k 개의 레코드 만 되돌릴 수있는 API으로 전화를 걸고 있습니다. API는 값을 반환 할 때까지 레코드를 계속 수신 할 수 있도록 보낼 값을 보내줍니다. 다음과 같이Observable 계속해서 API 호출 및 조건에 따라 매개 변수 변경

그래서 흐름은 간다 :

  • value 또는 done 로모그래퍼 reqMode을 포함하는 마지막 배열 응답을 검색 :

    1. GET 요청을 쿼리 매개 변수 reqMode=''을 확인합니다.
    2. value을받은 경우 동일한 요청을해야하지만 값이 reqMode 인 매개 변수를 보내야합니다.
    3. done을 받으면 첫 번째 호출 이후 모든 레코드를 중지하고 반환합니다.

  • 나는 값 때 subscribing normally의 첫 번째 세트를 얻을 수 있지만,이 문서를 읽은 후 내 시도를 할 것이다, 그러나 의미는하지 않습니다

    getRecords(){ 
        let url = this.url + 'reqMode='; 
        return this.http.get(url) 
          .doWhile() //What would I do here 
    } 
    

    관찰 가능한 함께 .doWhile을하려고 할 때 그 유형은 Observable<response>입니다. 나는 Observables를 사용하여 내가해야 할 일을 찾고있다.

    +0

    angular2의 rxjs5 베타와 함께 제공하고 당신이 늘 .doWhile을 사용할 수 있도록 문서에 기반을 ... 적어도 아직 : https://github.com/ReactiveX/rxjs/blob/master/MIGRATION.md#operators-renamed-or-removed. 대체 솔루션을 찾고 계십니까? 또는 rxjs4에 대해서만? – mrcolombo

    +0

    나는 대안이 있어도 괜찮습니다. – inspired

    답변

    4

    repeat()은 이것에 대한 좋은 연산자라고 생각하지 않습니다. 올바르게 이해하면 이전 요청의 응답을 기반으로 HTTP 요청을 반복하고 싶습니다. 을 동일한 요청을 여러 번 반복하려면 교환 원 repeat()이 좋습니다. 내가 요청을 시뮬레이션하고 값을 반환 할 of() 연산자를 사용 http://plnkr.co/edit/w0DdepslTaKrLSB3aIkA

    import {Observable, Subject} from 'rxjs'; 
    
    const result = new Subject(); 
    const closeBuffer = new Subject(); 
    const buffer = result.buffer(closeBuffer.asObservable()); 
    
    function sendHttpRequest(reqMode) { 
        return Observable.of('{"reqMode":' + reqMode + '}') 
        .map(response => JSON.parse(response)) 
        .concatMap(data => { 
         console.log('HTTP Response:', data); 
         // Add data to the buffer of results 
         result.next(data); 
    
         if (data.reqMode == 'done') { 
         // Return an empty value wrapped as an Observable so concatMap can work 
         // with it and emit onNext when it completes (which is immediately 
         // thanks to the `.of()` operator). 
         return Observable.of(null); 
         } else { 
         // Simulate that the next call returns 'done' 
         return sendHttpRequest('"done"'); 
    
         // Uncomment this for real usage 
         //return sendHttpRequest(data.reqMode); 
         } 
        }); 
    } 
    
    // Subscribe to the buffer where I'll receive the value. 
    buffer.subscribe(val => console.log('Next: ', val)); 
    
    // Simulate HTTP request with reqMode = 42 
    sendHttpRequest(42).subscribe(() => { 
        console.log('done'); 
        // Emit values from the buffer. 
        closeBuffer.next(null); 
        closeBuffer.complete(); 
    }); 
    

    :

    라이브 데모를 참조하십시오

    나는 reqMode"done"에 eqaul 때까지 자신을 호출 재귀 concatMap()을 사용할 것 Observable로 싸여있다. 나는 또한 Subject을 사용하여 buffer() 연산자를 사용하여 버퍼링 된 모든 응답을 보관합니다.응답의 마지막 배열을 얻기 위해 버퍼에 가입합니다 (이 코드를 함수에 포함하면 나중에 subscribe 할 수있는 buffer을 반환 할 가능성이 큽니다).

    응답은 다음입니다 :

    HTTP Response: Object {reqMode: 42} 
    HTTP Response: Object {reqMode: "done"} 
    Next: [Object, Object] 
    

    이 비슷한 질문을 참조하십시오 : Angular 2 + rxjs - how return stream of objects fetched with several subsequent http requests

    +0

    좋아 보인다! '재귀 '는 내 약점이었습니다. 새로운 단계로 나아가 야 할 때입니다. 지금 당장 이걸 시도해 보겠습니다. – inspired

    +0

    @ 답답합니다. 내 답변을 업데이트했는데,'done'까지 모든 응답을 쌓고 싶다는 것을 몰랐습니다. ?) 이제 조금 더 복잡해졌지만 여전히 이해할 수 있다고 생각합니다. – martin

    +0

    오, 나는 당신의 방법을 시도하고 그냥 모든 데이터 수집을 배열에 각 밀어,하지만 그때 내 배열을 외부 방법을 커플 것 같아요. – inspired

    2

    그래서 저는 랩핑 observer을 사용하고 .repeat()을 사용하여 이것을 수행 할 수있는 방법에 대한 예를 만들었습니다.

    모든 논리는 다른 또 다른 요청을 할 것입니다 나는 코드에 주석을 남아 있지만, 본질적으로, 그것은, 수를 증가합니다 HTTP 요청을하고 Checkout this plunker

    app.component.ts

    에 검색어 번호. 012에 도달 할 때까지 반복됩니다.

    "반복 조건"이 논리를 나타내도록 수정해야합니다.

    희망 하시겠습니까?

    +0

    확인해 보겠습니다. – inspired

    +0

    @mrcolombo - 매초마다 동작을 반복하도록 간격을 어떻게 추가 하시겠습니까? –

    +0

    @DonalRafferty는'.repeat()'전에'.delay (1000)'을 추가하면 1 초마다 실행하게됩니다. – mrcolombo