首页 文章

我应该在哪里编写Redux中的复杂异步流?

提问于
浏览
5

我想使用redux建模以下异步逻辑:

  • 用户操作会触发一系列异步API调用 .

  • 任何API调用都可能返回401状态(登录超时)

  • 如果API以401响应,则显示重新登录弹出窗口

  • 成功重新登录后,重新发出API调用并继续

我不知道在哪里放这个逻辑 . 操作不了解其他操作,他们只能访问调度,因此他们无法停止并等待它们完成 . 减速器无法发送,所以我不能把它放在那里......所以它住在哪里?自定义中间件? store.listen?在智能组件?

我目前正在使用redux-promise-middleware和redux-thunk . 如何最好地组织这种类型的流程 - 不需要买入像redux-saga或redux-rx等那样的东西?

还不确定透明地中断API调用以执行其他操作的最佳方法,即API调用不应在可选登录过程完成之后触发其已完成或失败的操作 .

1 回答

  • 1

    听起来像你想要一个生成Thunk的动作创建者,并将所有逻辑保留在Thunk中 . 实际上没有其他好方法可以保持您的API调用套件之间的关联,并确保在其中一个失败时取消所有其他调用 .

    • 在Thunk中,您将激活您的API调用,并收集他们的承诺:
    const call1 = promiseGenerator1();
    const call2 = promiseGenerator2();
    const call3 = promiseGenerator3();
    const allCallPromises = [call1, call2, call3];
    
    • 使用 all() promise处理程序来监视它们:
    const watcher = Promise.all(allCallPromises).then(allSuccess, anyFail);
    
    • 您的失败处理程序将:

    • 取消其余的承诺,如果其中任何一个401的 . (注意,这需要像Bluebird这样的库具有取消语义,或者您的承诺/请求的某种其他形式的扩充 . )

    • 调度操作或路由更改以触发重新登录窗口

    anyFail(error) => {
        if (error.status === 401) {
            allCallPromises.forEach((item)=> {item.cancel();});
            reLogin();
        }
    }
    
    • 然后,我倾向于让你的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 处理程序中,你只需调度异步调用的结果 .

相关问题