最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I repeat an ajax request until a condition is met with RxJS Observable? - Stack Overflow

programmeradmin0浏览0评论

I'm attempting to repeat a request until the response has data using RxJS, at which point I'd like to call a success (or failure) handler, but I'm having trouble w/RxJS. Here's my current approach:

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

Disclaimer: I'm quite new to RxJS....

I'm attempting to repeat a request until the response has data using RxJS, at which point I'd like to call a success (or failure) handler, but I'm having trouble w/RxJS. Here's my current approach:

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

Disclaimer: I'm quite new to RxJS....

Share Improve this question edited Sep 27, 2021 at 9:47 Srdjan Pazin 1582 silver badges9 bronze badges asked Apr 13, 2017 at 19:48 seitzejseitzej 1312 silver badges7 bronze badges 1
  • 2 So, what is the expected behaviour and what is the actual behaviour? – user3743222 Commented Apr 13, 2017 at 20:06
Add a comment  | 

3 Answers 3

Reset to default 6

It's simpler to repeat the request on an interval, filter on its result and take one emission.

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

It sounds like you want to suppress ajax results and retry until you get the response you want. I'd do it like so:

// 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);

Empty data is not an error so first we check if the data is empty and throw an error if it is. then retryWhen can be used to test for this error and retry as long as it's occurring.

.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)

  1. 暂无评论