Redux 可观察超时重试
Redux observable retry on timeout
我想使用 redux-observable 处理 ajax 超时,这样如果发生超时(比如 10 秒后),它将再重试请求两次(触发 SAVE_RETRYING
操作,这样 UI 可以通知用户它正在重试)。
对于任何其他类型的错误,或者如果我们已经重试了两次,它应该会失败并触发 SAVE_FAILURE
操作。
如果我使用 store.dispatch
触发 SAVE_RETRYING
操作,我可以让它工作,但收到关于此的弃用警告,我有点不知道如何以正确的方式做到这一点(添加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' }))
));
}
如何才能将 SAVE_RETRYING
操作添加到主流?谢谢
这并不理想,但您可以使用 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' });
});
}
我想使用 redux-observable 处理 ajax 超时,这样如果发生超时(比如 10 秒后),它将再重试请求两次(触发 SAVE_RETRYING
操作,这样 UI 可以通知用户它正在重试)。
对于任何其他类型的错误,或者如果我们已经重试了两次,它应该会失败并触发 SAVE_FAILURE
操作。
如果我使用 store.dispatch
触发 SAVE_RETRYING
操作,我可以让它工作,但收到关于此的弃用警告,我有点不知道如何以正确的方式做到这一点(添加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' }))
));
}
如何才能将 SAVE_RETRYING
操作添加到主流?谢谢
这并不理想,但您可以使用 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' });
});
}