2017-04-13 1 views
4

응답이 RxJS를 사용하여 데이터를 가질 때까지 요청을 반복하려고하는데,이 시점에서 성공 (또는 실패) 처리기를 호출하고 싶지만 RxJS가 문제가 있습니다.RxJS Observable로 조건이 충족 될 때까지 어떻게 ajax 요청을 반복합니까?

// ... redux-observable action observable 
.mergeMap(() => 
    fetchData() 
    .repeatWhen(response => 
     response.takeWhile(({ data }) => !data.length) 
     .of(response) 
    ) 
) 
.map(successFunction) 
.catch(failureFunction); 

면책 조항 : 여기 내 현재의 접근 방식이다 내가 RxJS 아주 새로운 해요 .... 당신이 아약스 결과를 억제하고 당신이 원하는 응답을 얻을 때까지 재 시도 할 같은

+1

따라서, 예상되는 동작은 무엇이며, 실제 행동은 무엇인가? – user3743222

답변

4

그것은 소리. 그래서처럼 할 거라고 : 먼저 우리는 데이터가 비어 있는지 확인하고 경우 오류가 발생하므로

// observable that will re-fetch each time it is subscribed 
const request = Observable.defer(() => fetchData()); 

// each time request produces its value, check the value 
// and if it is not what you want, return the request 
// observable, else return an observable with the response 
// use switchMap() to then subscribe to the returned 
// observable. 
const requestWithRetry = request.switchMap(r => 
    r.data.length ? Observable.of(r) : requestWithRetry); 
+0

브랜든, 나는 어리 석다. 이 작업은 재귀 적으로 어떻게 작동합니까? 잘못된 길이의 첫 번째 요청은 '요청'이 다시 구독되어 'fetchData'가 새로 실행되고 그 결과에 가입하게됩니다. 그러나 왜 그 결과는'switchMap'을 통해 다시 흐를까요? – user3743222

+0

@ user3743222 네가 맞습니다. 내가 뭘 생각했는지 확신 할 수 없어. 첫 번째 버전은'requestWithRetry'를 리턴해야합니다. : facepalm : – Brandon

+0

지금 받으십시오. 꽤 깔끔한. 이제 스택이 어떻게 진화하는지 궁금합니다. 그러나 제한된 금액의 retrials가있는 경우에는 어떤 문제도 있어서는 안됩니다. – user3743222

3

빈 데이터가 오류가 아닙니다. 이면 retryWhen을 사용하여이 오류를 테스트하고 오류가 발생하는 한 다시 시도 할 수 있습니다.

.mergeMap(() => 
    fetchData() 
    .map(data => { 
     if (!data.length) { 
      throw 'no data'; 
     } 
     return data; 
    }) 
    .retryWhen(errors => errors.takeWhile(error => error === 'no data')) 
) 
.map(successFunction) 
.catch(failureFunction); 
+0

던지지 않고이 작업을 수행 할 방법이 없습니까? – seitzej

+0

'repeatWhen'의 문제점은'data'에 접근 할 수 없다는 것입니다. 'repeatWhen'의 셀렉터는 소스의'onComplete' 통지만을받습니다. 따라서 그것은 귀하의 경우에 사용할 수 없게 만듭니다. 'repeatWhen'의 논리는 소스가 완성되었을 때 소스에 다시 등록하고 그 소스와 독립적 인 다른 조건으로 다시 구독하는 것입니다. 'retrywhen'의 장점은 오류 통지가 인수를 전달할 수 있다는 것입니다. 'onComplete' 알림에 해당하지 않습니다. – user3743222

+0

@seitzej'retryWhen'는 기본 관찰 항목이 오류 상태로 들어갈 때만 작동합니다. AFAIK이 작업은 던질 때 수행 할 수 있습니다. 왜 이것이 문제입니까? –

0

간격으로 요청을 반복하고, 결과를 필터링하고, 한 번 방출하는 것이 더 간단합니다.

Observable.timer(0, 500) 
    .flatMap(() => fetchData()) 
    .filter(r => r.data && r.data.length) 
    .take(1) 
    .timeout(10000) 

http://jsbin.com/cafericore/1/edit?js,console

관련 문제