I3.09.4don't decide on unconfirmed optimistic设计

依赖乐观结果做出后续决策的操作需要在真实结果返回前保持谨慎

别名: 乐观后决策 · 未确认就往下 · chain on optimistic · 过早承诺

概念解释

乐观结果一旦被当成真的,人会在它上面做下一件不可轻易收回的事:把「已发送」的消息转发给别人、用「已加入购物车」去结算、凭「已改好的权限」打开机密页。真实结果返回前保持谨慎指:后续决策要么等确认,要么被明确标成仍可收回,要么干脆在乐观窗口里不许做。

这和「不可逆操作不要乐观」不是同一刀。那里禁止把不可逆动作本身乐观掉;这里允许前面那步乐观,但禁止把未确认的结果当成后续动作的地基。

机制

乐观窗口里屏幕是真的、服务器可能是假的。后续决策把窗口里的值写进另一条因果链:转发引用了那条还可能被回滚的消息,结算引用了还可能没加进去的 SKU,导航引用了还可能被拒绝的权限。窗口闭合为失败时,回滚只能掀第一层;第二层已经跑到别人的收件箱、支付网关、或另一条路由。第二层没有对称回滚,于是出现「第一层倒了、第二层还在」的撕裂。

谨慎不是把产品冻住。它是把后续动作分成两类。一类读乐观值也无害(再点一次赞、再看一眼新标题)。一类会把乐观值输出到外部或不可收回处。第二类必须看见「未确认」这个门闩:按钮不可用、或可用但文案是「发送中,确认后再转发」、或转发本身被排队到确认之后。门闩是状态机上的守卫,不是文案装饰。

边界

纯展示的后续(根据乐观标题刷新导航栏文字)可以立刻变,回滚时一起变。用户自己心里做的决策(「我已经发了,去干别的」)拦不住,能拦的是产品提供的下一步入口。离线排队里,后续决策可以显式针对「待发送」而不是「已送达」——转发待发送应被拒绝或被标成「对方还收不到」。游戏或协作里以乐观位置做的本地预测(自己的角色先跑)是另一类,对端会纠正;那是预测,不是把未确认结果提交给支付。长时间确认(人工审核)会把谨慎窗口拉到分钟或天,后续动作更应默认锁住,而不是让人在审核期就把结果当完成来用。

怎么落地

  • 标出所有「读取某次未确认写入」的后续入口:转发、结算、分享、授权后的跳转。未确认时禁用,或改为排队到确认后执行。
  • 若必须可点,文案与状态要说「基于尚未确认的结果」,并在回滚时把后续动作一并停掉。
  • 不要在乐观成功时就发出对外副作用(推送、邮件、webhook)。副作用跟权威确认走。
  • 验证:乐观发送一条消息,在确认前点「转发」。若转发已到达第三方,而原消息随后回滚,撕裂成立。乐观加购后立刻结算:结算应等待加购确认,或在加购失败时自动退出结算并说明。权限乐观通过后打开机密页:权威拒绝时应立刻退出该页,而不是留在已经看过的内容里只把徽章改回去。

延伸

  • 同组I3.09.1 回滚时机需要清晰地把界面带回失败前的状态而非留下过渡痕迹 · I3.09.2 连续多个乐观操作叠加后,某一步失败的回滚范围需要明确边界 · I3.09.3 回滚提示应说明失败原因与是否可重试,而非仅呈现内容消失
  • 相邻I3.02 乐观更新 · I3.13 状态机的完备性与非法状态
  • 站内检索unconfirmed state · decision on optimistic · causal chain

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/I3.09.4