ice-lab / icestore

🌲 Simple and friendly state for React
MIT License
397 stars 35 forks source link

同时执行多个同步 Action 会出现前一个 action 的操作被覆盖问题 #66

Closed imsobear closed 4 years ago

imsobear commented 4 years ago
alvinhui commented 4 years ago

1.0 版本由于无法区分同异步 function, 所以同步 action 也被当做异步来做处理了。

为了解决这个问题,有几种可行的处理方案:

方案一

对于异步 action 不允许直接修改 state,调用同步方法:

{
  state: {},
  actions: {
    addBy: (prevState, payload) => ({...prevState, count: prevState.count + payload}), 
    addByAsync:  async(state, payload, actions) =>  {
      await delay(1000)
      actions.addBy(payload)
    }
  }
}

实现这样的 API 的前提是在内部能够对方法进行区分处理(判断是否是异步方法然后做特殊处理)。我留意到了在 stackoverflowTC 39 下的讨论。 目前来看,在编译后的代码中判断是否是异步似乎没有可行的方式。

因此该方案是不可行的

方案二

区分同步和异步方法:

{
  state: {},
  reduces: {
    addBy: (prevState, payload) => ({...prevState, count: prevState.count + payload}), 
  },
  effects: {
    addByAsync:  async(state, payload, actions) =>  {
      await delay(1000)
      actions.addBy(payload)
    }
  }
}

内部实现上来说比较简单,但对于用户来说其缺点是我之前所描述过的「纯对象好处」的反例:https://github.com/ice-lab/icestore/pull/59#issuecomment-586264440

在版本策略上:

方案三

为了尽量减少用户升级的成本和版本的分化,将「区分同步和异步方法」(参考方案二)作为新 feature。

发布 1.1.0:

imsobear commented 4 years ago

牵扯到两个变化:

  1. 异步 action 不允许修改 state
  2. actions 需要拆分成 reducers 和 effects

目前看来这两个变化是不可避免的,而且是两个实实在在的 break change,版本策略上发 1.1.0 风险是否可控(包括 icejs 里的依赖)?

alvinhui commented 4 years ago

严格地按照版本策略来说,这个 break change 确实应该升级为 2.0.0 。 icejs 的 plugin store 也需要发版本,同时需要添加错误提醒:发现它定义的 model 里有 actions 字段,提示它修改为 effects/reducers 的形式。

@chenbin92

alvinhui commented 4 years ago

最终决定使用方案三,PR:https://github.com/ice-lab/icestore/pull/65