如何在Redux-Saga中使用所有效果处理错误

时间:2018-08-03 11:02:18

标签: reactjs redux react-redux es6-promise redux-saga

我正在使用redux-saga同时启动多个请求,如the redux-saga docs中所述。 all效果具有all or nothing semantics,类似于Promise.all

只有所有effects成功了,yield all([...])成功了。但是,我正在执行几个请求,我希望其中一些失败,而某些成功。我想并行启动所有这些对象,并吸收那些成功的请求的响应。

因此,我尝试将请求包装到Promise中,无论请求是否成功,该请求始终可以解决:

// watcher saga
export function* watchMultipleRequests() {
  while(true) {
    const {ids} = yield take('VIDEOS_REQUEST');
    yield fork(doMultipleRequests, ids);
  }
}

// worker saga
export function* doMultipleRequests(ids) {
  const requests = ids.map(id => {
    // api.buildVideoRequest returns a promise once it is invoked
    const wrapper = ignoreErrors(api.buildVideoRequest, id);
    return call(wrapper);
  });
  try {
    const responses = yield all(requests);
    yield put({type: 'VIDEOS_SUCCESS', responses});
  } catch (error) {
    // should not happen because we are always resolving the promise
    console.log(error);
  }
};

export function ignoreErrors(fn, ...args) {
  return function* () {
    yield new Promise(function (resolve) {
      return fn(...args)
        .then(response => {
          console.log('success = ', response);
          resolve(response);
        })
        .catch(response => {
          console.log('error = ', response);
          resolve(response);
        });
    });
  }
}

我想处理reducer中的错误情况。但是,如果我触发n请求,则responses数组将包含nundefined。有谁知道为什么它不起作用?

1 个答案:

答案 0 :(得分:0)

问题在于ignoreErros函数是生成器函数。 像这样实现:

export function ignoreErrors(fn, ...args) {
  return () => {
    const ignoreErrorCallback = (response) => response;
    return fn(...args).then(ignoreErrorCallback, ignoreErrorCallback);
  };
}

足够了。