如何在 redux-saga 中使用 all effect 处理错误

How to deal with errors using all effect in 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。有没有人知道为什么这不起作用?

问题是 ignoreErros 函数是一个生成器函数。 像这样实现它:

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

足够了。