Javascript 在Redux中,我应该在哪里组合复杂的异步流?

Javascript 在Redux中,我应该在哪里组合复杂的异步流?,javascript,redux,react-redux,redux-thunk,redux-promise,Javascript,Redux,React Redux,Redux Thunk,Redux Promise,我想使用redux对以下异步逻辑建模: 用户操作触发一系列异步API调用 任何API调用都可能返回401状态(登录超时) 如果API响应401,则显示重新登录弹出窗口 成功重新登录后,重新发出API调用并继续 我不知道该把这种逻辑放在哪里。操作不知道其他操作,它们只能访问dispatch,因此不能停止并等待它们完成。减速器没有调度的权限,所以我不能把它放在那里…那么它住在哪里?定制中间件?商店,听着?在智能组件中 我目前正在使用redux promise中间件&redux thunk。如何最好地

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

  • 用户操作触发一系列异步API调用
  • 任何API调用都可能返回401状态(登录超时)
  • 如果API响应401,则显示重新登录弹出窗口
  • 成功重新登录后,重新发出API调用并继续
  • 我不知道该把这种逻辑放在哪里。操作不知道其他操作,它们只能访问dispatch,因此不能停止并等待它们完成。减速器没有调度的权限,所以我不能把它放在那里…那么它住在哪里?定制中间件?商店,听着?在智能组件中

    我目前正在使用redux promise中间件&redux thunk。如何最好地组织这种类型的流——而不需要购买redux saga或redux rx之类的东西


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

    我觉得您需要一个生成Thunk的操作创建者,并将所有逻辑保留在Thunk中。实际上,没有其他好方法可以保持API调用套件之间的关联,并确保在其中一个失败时取消所有其他调用

  • 在这种情况下,您将启动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();
          }
      }
      
  • 然后,我倾向于让您的重新登录组件担心再次触发相同的复杂操作,以发出所有调用

  • 但是,如果您的API调用套件在某种程度上是可变的或特定于上下文的,您可以从
    anyFail
    处理程序内部将所需的API调用缓存在存储区中。有一个可存放
    actionPendingReLogin
    的减速器。编写一个操作,该操作将重新激发与上次相同的调用,然后将其分派:

    dispatch(createAction('CACHE_RELOGIN_ACTION`, actionObjectToSaveForLater));
    
    (或者,缓存您使用的任何动作创建者。)

    然后,在成功重新登录后,您可以:

    const action = store.getState('actionPendingReLogin');
    dispatch(action);
    // or:
    const actionCreator = store.getState('actionPendingReLogin');
    dispatch(actionCreator());
    
  • 噢:在
    allSuccess
    处理程序中,您只需分派异步调用的结果