Flux/Alt Basic 异步示例抛出“无法在调度中间调度”

Posted

技术标签:

【中文标题】Flux/Alt Basic 异步示例抛出“无法在调度中间调度”【英文标题】:Flux/Alt Basic async example throws "Cannot dispatch in the middle of a dispatch" 【发布时间】:2016-02-20 07:38:33 【问题描述】:

我正在努力解决 Flux 向我抛出的 Cannot dispatch in the middle of a dispatch 错误,并举了一个基本示例。

在我看来,我的AuthActions 上有一个触发socialLogin(token) 操作的按钮。在我的操作中使用 Alt,我 generateActions('login');

我的socialLogin 方法执行一个异步 API 请求,该请求返回一个承诺(Api 是一个使用请求库的简单类):

// AuthActions
socialLogin(type, access_token) 
    Api.request('get', 'auth/social',  type, access_token )
       .then((payload) => 
           if (payload.code !== 'OK') 
               // Do something...
            else 
               this.actions.login(payload.data.token);
           
       )
       .catch((response) => 
           console.log('ERROR', response);
           // Do something....
       );
    this.dispatch();

Store onLogin 方法目前什么都不做。

但是运行这个会抛出/捕获错误Uncaught (in promise) Error: Invariant Violation: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.(…)

我不明白为什么,在阅读了许多问题/文章后 - this.dispatch() 不应该“解决”当前正在调度的操作?

我将如何在此处触发其他操作,甚至触发多个操作(登录、使用其他外部操作等)。

谢谢!

【问题讨论】:

【参考方案1】:

在动作内部,只返回一个类似的承诺:

 socialLogin(type, access_token) 
  return (dispatch) => 
    dispatch(type:type, accessToken:access_token);
    return new Promise((resolve,reject)=>
      Api.request('get', 'auth/social',  type, access_token )
      .then((payload) => 
       if (payload.code !== 'OK') 
           // Do something...
        else 
           this.actions.login(payload.data.token);
       
       resolve(payload);
       )
       .catch((response) => 
       console.log('ERROR', response);
       // Do something....
       reject(response);
       );
    
  


有时在容器/控制器视图中,您可能会因为此操作而调用操作,这将导致相同的错误。在这种情况下,只需在调度中使用 defer 选项调用任何后续操作,例如:

  myaction.actionname.defer(options);

【讨论】:

【参考方案2】:

您需要的是this.actions.myAnotherAction(),其中myAnotherAction 在您的情况下是AuthActions 中的另一个操作。看看

【讨论】:

【参考方案3】:

我认为在您的示例中,您可以完全省略 this.dispatch(); 行,并且应该这样做。 action creator 函数socialLogin 是作为 dispatch 本身的一部分调用的,因此不允许调用 dispatch。如果您确实想在登录过程开始时分派一个 socialLogin 操作(例如,允许放置一个微调器或其他东西),您可以返回您想要分派的有效负载。例如将this.dispatch(); 替换为

return  type, access_token ; 

这样,如果商店想要了解流程的开始,他们就可以收听 socialLogin。

【讨论】:

以上是关于Flux/Alt Basic 异步示例抛出“无法在调度中间调度”的主要内容,如果未能解决你的问题,请参考以下文章

颜色在开始示例opengl中不起作用

C++/CLI 中的 Super Basic OpenFileDialog 抛出错误

c++ 在抛出 'std::out_of_range' 实例后调用终止 what(): basic_string::insert

React/ Flux 前端和 Meteor 后端

问题 - 在抛出 'std::out_of_range' what(): basic_string::substr:? 的实例后调用 C++ 终止

在抛出 'std::length_error' what(): basic_string::_S_create 的实例后调用终止