Redux Saga中是否存在类似Promise.any的效果组合器?
实现Redux Saga版的
Promise.any效果组合器 Redux Saga提供的all([...effects])效果组合器和Promise.all行为类似,但官方没有提供对应Promise.any的实现。我们需要的组合器要满足以下要求:
- 同时运行传入的所有effects
- 只有当所有effects都执行失败时才抛出错误,否则视为执行成功
- 所有effects都失败时,抛出包含全部错误的
AggregateError - 只要有一个effect成功,就返回空值(或首个成功结果)
使用示例
在合并多个拆分的saga时,这个组合器非常实用——它不会因为某个saga失败就立刻终止,而是会等待所有effects执行完成:
export function* getHomeDataSaga() { yield* any([ call(getTopUsersSaga, { payload: undefined }), call(getFavoritesSaga, { payload: undefined }), call(getTrendingTokensSaga, { payload: undefined }), call(getTopCollectionsSaga, { payload: { itemsPerPage: 9, page: 1 } }), ]); }
最终实现(基于Martin Kadlec的思路)
export function* anyCombinator(effects: SagaGenerator<any, any>[]) { const errors = yield* all( effects.map((effect) => call(function* () { try { yield* effect; return null; } catch (error) { return error; } }), ), ); if (errors.every((error) => error !== null)) { throw new AggregateError(errors); } }
实现逻辑说明
- 用
all批量执行每个包装后的effect:每个effect都被包裹在一个自执行的saga函数中,通过try/catch捕获错误 - 单个effect执行成功时返回
null,失败时返回对应的错误对象 - 所有effect执行完成后,检查结果数组:如果所有元素都是错误对象(没有
null),则抛出包含全部错误的AggregateError;否则直接结束,不抛出错误
内容的提问来源于stack exchange,提问作者nezort11
相关产品推荐
相关产品推荐

