Redux Observable catchError中触发多action实现延迟关闭告警
实现方案
你可以使用concat操作符合并两个Observable,确保先同步执行清空状态、创建告警的action,再执行延迟的关闭告警action,调整后代码如下:
export const authWithEmailPasswordEpic = action$ => action$.pipe( filter(authUser.match), switchMap(({payload}) => defer(() => from(firebaseEmailPasswordAuth(payload)).pipe( mergeMap(() => of(clearAlertState(), stopLoading())), catchError(err => concat( of(clearState(), createAlert({ status: err.code, alertType: RED_ALERT, alertTitle: err.message })), of(toggleAlert()).pipe(delay(5000)) ) ) ) ) ) );
注意不要使用merge操作符,否则两个流会同时执行,导致告警刚创建就被关闭,concat的顺序执行特性刚好匹配该需求。
更优方案
建议将告警自动关闭逻辑抽为通用独立epic,避免每个业务场景重复编码,提升复用性:
export const autoDismissAlertEpic = action$ => action$.pipe( filter(createAlert.match), switchMap(() => of(toggleAlert()).pipe(delay(5000))) );
该方案的优势包括:
- 所有创建告警的场景都会自动触发5秒后关闭逻辑,无需在每个业务epic中重复编写延迟代码
- 后续需要调整自动关闭时长、增加特殊场景排除规则时,只需修改该通用epic即可
- 业务代码更简洁,仅需要关注告警创建的业务逻辑本身
另外该方案天然解决了边界问题:如果用户在5秒内手动关闭告警、或者触发了新的告警,switchMap会自动取消之前未执行的延迟关闭逻辑,不会出现误关新告警的问题,鲁棒性更高。
内容的提问来源于stack exchange,提问作者Jon Flynn
相关产品推荐
相关产品推荐

