从 redux-saga all 中获取结果,即使有失败

Posted

技术标签:

【中文标题】从 redux-saga all 中获取结果,即使有失败【英文标题】:Getting results from redux-saga all, even if there are failures 【发布时间】:2022-01-20 16:10:39 【问题描述】:

我有一个场景,我需要并行进行多个 api 调用。目前,代码使用 redux-saga all 来执行此操作:

try 
    const results = yield all(
      someIds.map(id =>
        call(axios.delete, `/api/somewhere/items/$id`)
      )
    );
    console.log(results);
    yield put(someSuccessFunction)
 catch(e) 
    yield put(someFailureFunction)

如果所有调用都成功,results 将正确记录为 axios 响应数组,包括headersrequeststatus 等。但是,即使单个调用失败,代码跳转到catch 块。我无法知道哪个调用失败了。

我已经阅读了How to handle array of requests in redux saga,但在其中的示例中,似乎接受的答案是在每次通话的基础上跟踪成功或失败。我需要知道 all 调用是否成功,如果是,则发送成功操作。如果任何调用失败,我需要知道哪些调用失败,并调度失败或部分失败操作。它可能看起来像这样:

try 
    const results = yield all(
      someIds.map(id =>
        call(axios.delete, `/api/somewhere/items/$id`)
      )
    );
    const success = results.every(result => result.status === 200);
    const failure = results.every(result => result.status !== 200);
    const partialFailure =
      results.some(result => result.status === 200) &&
      results.some(result => result.status !== 200);
    
    if (success) put(someSuccessAction);
    if (failure) put(someFailureAction);
    if (partialFailure) put(somePartialFailureAction);

 catch(e) 
    yield put(someFailureFunction);

但是当任何500 响应将我们跳过到 catch 块时,我似乎无法掌握如何检索结果数组。这样做的最佳策略是什么?

【问题讨论】:

【参考方案1】:

诀窍是为每个请求设置一个单独的 try..catch,并将成功或失败的结果映射到一个结构中,然后您可以在该结构上运行各种数组操作。本质上,它的工作方式类似于Promise.reflect。在这种情况下,它可能看起来像这样:

function* deleteById(id) 
  try 
    const result = yield call(axios.delete, `/api/somewhere/items/$id`)
    if (result.status !== 200) throw new Error('Invalid status')
    return v: result, status: 'fulfilled'
   catch (err) 
    return e: err, status: 'rejected'
  


function* deleteSaga() 
  const results = yield all(
    someIds.map(id => call(deleteById, id))
  )
  const success = results.every(result => result.status === 'fulfilled')
  const failure = results.every(result => result.status === 'rejected')
  //...


为了便于阅读,我已将请求按 id 分离到自己的 saga 中,尽管它也可以是内联生成器。

【讨论】:

以上是关于从 redux-saga all 中获取结果,即使有失败的主要内容,如果未能解决你的问题,请参考以下文章

使用 redux-saga 对 redux store 进行异步调用

即使在获取数据后,React Component的render方法也会被调用两次

如何使用 redux-saga 在 getInitialProps 中获取数据。然后在 getInitialProps 方法中从 redux store 获取响应?

React 通用 redux-saga 内存泄漏

P18:Redux-saga获取TodoList列表

MySQL - 使用 UNION ALL 获取错误的表字段但结果是正确的