Javascript 反应流量-调度中的调度-如何避免?

Javascript 反应流量-调度中的调度-如何避免?,javascript,reactjs,flux,Javascript,Reactjs,Flux,我似乎遇到了一种情况,在这种情况下,我无法避免不断变化的内部调度问题 我读过一些关于这个问题的类似问题,但是除了setTimeouthacks之外,没有一个是好的解决方案,我想避免这些问题 实际上我用的是代替通量,但我认为概念是一样的 脚本 设想一个最初呈现登录表单的组件。当用户登录时,这会触发一个XHR,该XHR最终以身份验证信息(例如用户名)作出响应,然后根据身份验证信息获取一些安全数据,并呈现它而不是登录表单 我遇到的问题是,当我试图根据XHR响应启动一个获取数据的操作时,它仍在调度LOG

我似乎遇到了一种情况,在这种情况下,我无法避免不断变化的内部调度问题

我读过一些关于这个问题的类似问题,但是除了
setTimeout
hacks之外,没有一个是好的解决方案,我想避免这些问题

实际上我用的是代替通量,但我认为概念是一样的

脚本 设想一个最初呈现登录表单的组件。当用户登录时,这会触发一个XHR,该XHR最终以身份验证信息(例如用户名)作出响应,然后根据身份验证信息获取一些安全数据,并呈现它而不是登录表单

我遇到的问题是,当我试图根据XHR响应启动一个获取数据的操作时,它仍在调度
LOGIN\u响应
操作,并触发可怕的错误

Error: Invariant Violation: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.
例子 我创建了一个示例来演示这个问题

我有一个
Wrapper
组件,它根据用户是否在
MyStore
中设置,呈现一个登录按钮或一个
Contents
子组件

  • 首先,登录按钮呈现在
    Wrapper
    组件中
  • 单击按钮可分派
    登录
    操作
  • 延迟后,
    LOGIN\u响应
    操作被调度(通过)
  • 此操作将触发MyStore更新用户名
  • Wrapper
    组件观察存储更改并更新其状态
  • 这将导致
    包装器
    呈现
    内容
    组件,而不是登录按钮
  • Content
    组件在装载时尝试分派
    FETCH\u DATA
    操作,该操作失败,因为分派器仍在分派
    LOGIN\u响应
    。(如果我将
    FETCH_DATA
    dispatch包装在
    setTimeout
    中,它可以工作,但感觉像是黑客攻击)
  • 这种变化似乎是一种常见的情况。事实上,几乎所有相关问题都有类似的情况,但没有好的或具体的答案


    这个数据流是否有本质上的问题?这样做的正确方法是什么?

    这是许多库中在
    componentDidMount
    中分派组件的常见问题。解决方案是在React的批量更新中封装调度;幸运的是,Alt允许您使用
    batchingFunction
    选项执行此操作:

    var alt = new Alt({
      // React.addons.batchedUpdates is deprecated:
      // batchingFunction: React.addons.batchedUpdates
    
      // use this instead in newer versions of React
      // see https://discuss.reactjs.org/t/any-plan-for-reactdom-unstable-batchedupdates/1978
      batchingFunction: ReactDOM.unstable_batchedUpdates
    });
    

    请参阅,以获取一个工作示例以及在不同框架中对同一问题的描述。

    我相信我们忠实的朋友调度员有权投诉

    在给出结论之前,我将尝试描述一种假设情况。假设一个应用程序有两个存储S1和S2以及两种操作A1和A2。通常通量实现的正确流程应该是:

  • 组件触发动作A1(基本上是调度)
  • 单个调度器将相应的有效负载分配给所有注册的存储
  • S1消耗有效载荷并可能更新其状态
  • 在S1中侦听更改的所有组件都会检查它们感兴趣的更改,并可能更新其内部状态(可能会触发重新渲染)
  • S2消耗。。。(如步骤3所示)
  • 侦听S2中更改的所有组件。。。(如步骤4所示)
  • 现在,所有存储都完成了对动作有效载荷的处理,组件可以启动新动作(A1或A2)
  • 与传统MVC相比,使用Flux的最大优势之一是Flux为您提供了可预测性的天赋。这种感觉使开发人员相信,通过正确应用Flux哲学,他们确信执行顺序总是类似于:

    A1>S1>S2>A2>S1>S2>

    这是一个非常大的问题,尤其是在试图找到bug的来源时。有人可能会争辩说,强制执行可预测的事件链可能会导致一些低效率,他可能是对的,特别是在处理异步调用时,但这是您为拥有如此强大的功能而付出的代价

    由于异步调用,事情可能会变得有点混乱。可能会发生以下一连串事件:

    A1>S1>A2>S2>S1>S2>

    也许你的应用程序可以很好地处理这一系列事件,但这种“不可预测性”损害了Flux单向数据流背后的基本动机

    我觉得社会上对如何处理这类情况没有共识,但我会分享我的一般解决办法:“为了可预测性,确保在最后一项行动完全得到处理之前,不要触发任何新的行动”

    一种方法是下载应用程序在触发任何其他操作之前成功重新渲染所需的所有必要(新)数据。在您的示例中,这可以通过以下方式实现:首先下载LOGIN_响应和FETCH_data操作中涉及的数据,并将其包装在单个有效负载中,然后将其分派,这样所有组件都将在存储中拥有所需的数据,而无需要求更多