全部从 redux-saga 获取结果,即使有失败
Getting results from redux-saga all, even if there are failures
我有一个场景需要并行进行多个 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 响应数组,其中 headers
、request
、status
等。但是,即使单个调用失败,代码也会跳转到 catch
块。我无法知道哪个调用失败了。
我已阅读 ,但在此处的示例中,公认的答案似乎是在每次调用的基础上跟踪成功或失败。我需要知道 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 块时,我似乎无法掌握如何检索结果数组。这样做的最佳策略是什么?
诀窍是为每个请求设置一个单独的 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 中。
我有一个场景需要并行进行多个 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 响应数组,其中 headers
、request
、status
等。但是,即使单个调用失败,代码也会跳转到 catch
块。我无法知道哪个调用失败了。
我已阅读
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 块时,我似乎无法掌握如何检索结果数组。这样做的最佳策略是什么?
诀窍是为每个请求设置一个单独的 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 中。