如何重复ajax请求,直到RxJS Observable满足条件?
我试图重复一个请求,直到响应中有使用RxJS的数据,此时我想调用成功(或失败)处理程序,但是我遇到了RxJS问题。这是我目前的做法:如何重复ajax请求,直到RxJS Observable满足条件?
// ... redux-observable action observable
.mergeMap(() =>
fetchData()
.repeatWhen(response =>
response.takeWhile(({ data }) => !data.length)
.of(response)
)
)
.map(successFunction)
.catch(failureFunction);
免责声明:我很新的RxJS ....
这听起来像你想压制阿贾克斯的结果和重试,直到你得到你想要的答复。我愿意做它像这样:所以首先我们检查,如果数据是空的,如果它是抛出一个错误
// 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);
布兰登,我傻眼了。这是如何递归的?具有错误长度的第一个请求会导致'request'被再次订阅,导致'fetchData'的新执行并订阅该结果。但为什么这个结果会再次通过'switchMap'流动呢? – user3743222
@ user3743222是的,你是对的。不知道我在想什么。第一个版本应该返回'requestWithRetry'。 :facepalm: – Brandon
我现在明白了。很简约。现在我想知道堆栈是如何演变的。但在任何情况下,对于有限的再审,都不应该有任何问题。 – user3743222
空的数据是不是一个错误。 然后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);
没有办法做到这一点没有投掷? – seitzej
'repeatWhen'的问题是你没有访问'data'。 'repeatWhen'中的选择器只收到源的“onComplete”通知。因此,这使得它不适用于你的情况。 “repeatWhen”的逻辑是,你在该源完成时重新订阅源,然后在独立于该源的其他条件下重新订阅源。 'retrywhen'的优点是错误通知允许传递参数。 'onComplete'通知不是这样的情况 – user3743222
@seitzej'retryWhen'只在潜在的observable进入错误状态AFAIK时才起作用,这可以在投掷时完成,为什么这是一个问题? –
在间隔上重复请求,过滤其结果并采取一次发射更简单。
Observable.timer(0, 500)
.flatMap(() => fetchData())
.filter(r => r.data && r.data.length)
.take(1)
.timeout(10000)
那么,什么是预期的行为,什么是实际行为? – user3743222