Redux可观察到的超时重试

时间:2018-08-19 04:05:26

标签: redux rxjs rxjs5 redux-observable

我想使用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' })) )); } 动作一直流到主流?谢谢。

1 个答案:

答案 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' });
    });
}