我想使用redux-observable处理ajax超时,这样,如果发生超时(例如10秒钟后),它将再次重试请求两次(每次触发SAVE_RETRYING
操作,以便UI可以通知用户正在重试。)
对于任何其他类型的错误,或者如果我们已经重试两次,它应该会失败并执行SAVE_FAILURE
操作。
如果我使用SAVE_RETRYING
触发store.dispatch
动作,但可以得到弃用警告,那我就可以使它正常工作,我有点想找出如何以正确的方式进行操作(添加{{ 1}}到史诗返回的流中。
这就是我所拥有的(简体):
SAVE_RETRYING
如何使function saveEpic(action$, store) {
return action$.ofType('SAVE_CLICKED')
.mergeMap(action => (
ajax({
url: '/a-long-request',
})
.timeout(10000)
.map(() => ({ type: 'SAVE_SUCCESS' }))
.retryWhen(errors => (
errors.scan((count, e) => {
if (count >= 2 || e.name !== 'TimeoutError') {
throw e;
} else {
store.dispatch({ type: 'SAVE_RETRYING', count });
return count + 1;
}
}, 0)))
.startWith({ type: 'SAVE_STARTED' })
.catch(() =>
Observable.of({ type: 'SAVE_FAILURE' }))
));
}
动作一直流到主流?谢谢。
答案 0 :(得分:1)
这不是理想的选择,但是您可以使用catch
和未记录的第二个参数(可观察到的源)重新订阅。我不喜欢的缺点是您必须在mergeMap
回调闭包中计算重试次数。
function saveEpic(action$, store) {
return action$.ofType('SAVE_CLICKED')
.mergeMap(action => {
let retries = 0;
return ajax({
url: '/a-long-request',
})
.timeout(10000)
.map(() => ({ type: 'SAVE_SUCCESS' }))
.catch((error, source) => {
retries += 1;
if (retries >= 2 || error.name !== 'TimeoutError') {
return Observable.of({ type: 'SAVE_FAILURE' });
}
return source.startWith({ type: 'SAVE_RETRYING', count: retries });
})
.startWith({ type: 'SAVE_STARTED' });
});
}