一个「必须刷新页面」的 bug:状态机没设计好
· 2 分钟阅读
工具上线后收到一句反馈:压缩完对结果不满意,想换个质量再来一次,发现按钮是灰的,只能刷新页面重来。
第一反应是「用户操作不对」,第二反应是「不对,这是我的问题」。
现象
- 图片压完,状态变成「完成」;
- 主按钮的判断条件是「有没有待处理的图」,此时数量为 0,于是按钮禁用;
- 改质量、改格式,已完成的结果不会失效,也没有任何「重跑」入口;
- 唯一出路是删掉图片重新选——体验上等于必须刷新。
根因
我把「能不能点」绑在了「有没有 pending」上,但一个工具页的状态远不止两种。真实状态至少有:
待处理 → 处理中 → 完成,再加上一层 结果是否对应当前参数。
少建了最后一维,就出现了「结果还在,但没法重算」的死角。
修法
- 按钮文案跟着状态走:有待处理项时显示「开始压缩(N)」,全部完成后变成「重新压缩」,永远可点;
- 给结果记参数签名:每条结果存下生成时的
format:quality:maxEdge,和当前设置不一致就标记为「过期」; - 显示提示:有过期结果时提示「设置已修改,点重新压缩按当前参数重跑」;
- 重跑前回收内存:旧的
blob:地址逐个revokeObjectURL,避免反复压缩把内存堆满。
实测同一张图:默认质量 96 KB → 质量 40 后 57 KB → 转 WebP 后 18 KB,全程没刷新。
经验
异步工具页别用布尔量拼状态(busy / hasResult / disabled 各管一摊),很快就会出现互相矛盾的组合。把状态和「结果对应的参数」显式建模,bug 会少一大半。
