Redux 如何保证没有竞争条件?

How can Redux guarantee no race condition?

我最近了解了 Redux。
我很理解这个概念,但我没有弄清楚 official documentation:

中的这一行

Because all changes are centralized and happen one by one in a strict order, there are no subtle race conditions to watch out for.

Redux 如何保证没有微妙的竞争条件?

确实,我可以想象这个场景(按顺序):

  1. 一些组件分派 ACTION_TYPE_1。
  2. 一些组件分派 ACTION_TYPE_2。
  3. ACTION_CREATOR_1 发出 ajax 调用以获取一些数据。
  4. ACTION_CREATOR_2 发出 ajax 调用以获取一些数据。
  5. ACTION_CREATOR_2 在 之前 ACTION_CREATOR_1 处理抓取的数据。
  6. 由于这种竞争条件,可能会出现奇怪的行为?

所以动作创建者调度将按顺序应用,但这些动作创建者的实现可能不会按顺序应用,可能导致非确定性代码。

如何计算报价?

我可以理解,对于 Redux,有一种 trace 关于调度动作的历史(有助于理解运行时的程序工作流),但是真正的实现呢那些行动?

我刚刚遇到 this point,非常有意义,@DanAbramov 本人。

我认为它很好地回答了我的 OP。

重点是只要动作的调度保持同步(尽管动作创建者的内部进程可能根本不同步),就很容易快速找出一个通过建立和记录调度操作的历史来解决竞争条件(或其他有关非确定性的问题)。
特别是很容易重现 "weird" 状态,然后找出如何避免它(如 Event-Sourcing)。

没有任何同步可见的时间点,很难掌握发生的事情;这就是 Redux 带来好处的原因。

Redux 不会避免竞争条件,但确实会大大减少微妙(难以分析)竞争条件,如文档所述。

  1. Javascript 是线程安全的,所以 2 个函数不能同时 运行。

  2. Redux 不了解异步操作,它只关心当前状态、派发给它的事件以及如何将当前状态转换为给定事件的其他状态。

  3. 因此确保动作调度顺序是你的责任,这不是 Redux 的责任。

  4. 如果有两个事件,X 和 Y,并且您想在处理 X 之前阻止处理 Y,那么您可以使用一些状态属性在 Redux 状态中跟踪它。因此,您可以轻松地在处理 X 之前阻止处理 Y。

  5. 人们可能希望申请的异步操作和错误处理有太多不同的要求。因此很难为您正在谈论的 "race conditions" 提供通用解决方案。

  6. 设计您的系统,找到所有边缘情况,并为您可以拥有的每个边缘情况创建一个新的 event/event name/event 处理。然后在你的 redux reducer 中处理它们,进行适当的状态转换。在 Web 应用程序中,没有什么是致命的错误(要求用户刷新浏览器并不是一个好 UI/UX)所以你必须从每一个可能的边缘情况中恢复,因此抛出错误没有多大意义。