在Redux中,我应该在哪里编写复杂的异步流
Where should I Compose Complex Asynchronous Flows in Redux?
我想使用redux对以下异步逻辑进行建模:
- 用户操作触发一系列异步API调用
- 任何API调用都可能返回401状态(登录超时)
- 如果API响应401,则显示重新加载弹出窗口
- 重新登录成功后,重新发出API调用并继续
我不知道该把这个逻辑放在哪里。操作不知道其他操作,他们只能访问调度,所以他们不能停下来等待它们完成。Reducers无法访问调度,所以我不能把它放在那里……那么它住在哪里?自定义中间件?store.listen?在智能组件中?
我目前正在使用redux promise中间件&redux thunk。如何最好地组织这种类型的流程——而不需要购买redux传奇或redux rx等?
也不确定透明地中断API调用以执行其他操作的最佳方式,即API调用在可选登录过程完成之前不应触发其已完成或失败的操作。
在我看来,你似乎想要一个生成Thunk的动作创建者,并在Thunk中保留所有这些逻辑。确实没有其他好方法可以保存API调用套件之间的关联,并确保在一个调用失败时取消所有其他调用。
-
在那次Thunk中,你会触发你的API调用,并收集他们的承诺:
const call1 = promiseGenerator1(); const call2 = promiseGenerator2(); const call3 = promiseGenerator3(); const allCallPromises = [call1, call2, call3];
-
使用
all()
承诺处理程序来监视它们:const watcher = Promise.all(allCallPromises).then(allSuccess, anyFail);
-
您的故障处理程序将:
- 取消其余的承诺(如果有401的话)。(注意,这需要像Bluebird这样具有取消语义的库,或者其他形式的承诺/请求增强。)
-
调度一个操作或路由更改以触发重新登录窗口
anyFail(error) => { if (error.status === 401) { allCallPromises.forEach((item)=> {item.cancel();}); reLogin(); } }
-
然后,我倾向于让您的重新登录组件担心再次重新启动相同的复杂操作,以发出所有调用。
-
然而,如果您的API调用套件是可变的或特定于上下文的,您可以从
anyFail
处理程序内部将所需的调用缓存在存储中。有一个可以存放actionPendingReLogin
的减速器。编写一个操作,重新启动与上次相同的调用,然后发送:dispatch(createAction('CACHE_RELOGIN_ACTION`, actionObjectToSaveForLater));
(或者,只需缓存您使用的任何动作创建者。)
然后,在成功重新登录后,您可以:
const action = store.getState('actionPendingReLogin'); dispatch(action); // or: const actionCreator = store.getState('actionPendingReLogin'); dispatch(actionCreator());
哦:在allSuccess
处理程序中,您只需分派异步调用的结果。
相关文章:
- esri javascript异步打印
- JavaScript异步问题
- $translateProvider.useStaticFilesLoader的Angular Translate异步定
- 异步facebook功能
- 异步并行错误
- 在Redux中,我应该在哪里编写复杂的异步流
- 角度异步http自动完成
- 将复杂对象从angular js传递到web api,它总是返回404
- 如何从SeleniumWebdriver获取异步Javascript响应
- dropdown.js中的复杂事件处理
- 您有更好的动态方式来缩短复杂的代码jquery吗
- 相当复杂的Regex
- 如何使用异步调用更改工厂的变量
- 用Javascript重新格式化复杂文本日期字符串的更好方法
- 在等待异步任务时永久循环
- 如何在异步函数中使用javascript对象
- 调用后不异步Ajax忽略函数
- Javascript 异步用于复杂计算,但不是 ajax 调用
- 如何包装需要异步调用的复杂 if-then 语句
- Ember:解决复杂的异步承诺