延迟保存要捕获创建时的实体
症状
「笔记无法编辑,始终显示同一份笔记」——切来切去内容互相覆盖,看起来像编辑器坏了。
根因链
- 正文编辑不是每敲一字就保存,而是 1 秒 debounce。
- 用户编辑 A 后 1 秒内切到 B。
- B 的完整正文还没加载完,父层传给编辑器的
note短暂变成null。 - 旧逻辑在
note === null时直接return,没有把 A 的待保存内容 flush 掉。 - 计时器随后触发,保存逻辑默认取「当前 active tab id」。
- 此时 active tab 已是 B → A 的正文被写进 B。
两层防护
note === null时,也用lastNoteIdRef把上一条的 pending title/content 保存到旧 id;- debounce 创建时就捕获当前
note.id,触发时显式传这个 id,不再临时读当前 active tab。
可迁移的判断
「延迟执行 + 读取全局当前值」是一类通用 bug 形状,和业务无关:
- 定时器 / debounce / 动画帧 / 请求重试,只要回调里读的是共享的可变当前指针,切换对象就会写错目标;
- 修法统一是闭包捕获 + 显式传参,不要依赖回调执行时的环境状态;
- 加载态(
null/ loading)不是「什么都不用做」,而是最需要 flush 的时刻。
相关
- 编辑即时反馈与落盘延迟分离 —— 同一保存链路的另一半:延迟多久、延迟什么
- 过期响应不能覆盖当前编辑内容 —— 同一条保存链路的第三种乱序:过期响应回写正文