页面说未完成接口说已完成:如何找到那个说真话的地方
页面说「未完成」,接口说「已完成」
这周我一直在做同一件事:每天在某个平台上完成几个任务,攒积分换东西。
过程中遇到一个反复出现的问题——页面显示的状态,和真实状态不一致。
最典型的一次:某个任务我已经做完了,页面上还挂着「未完成」。我以为是没做成,又做了一遍,做了三遍还是「未完成」。后来翻了接口才发现,第一次就已经成功了。
一、UI 是结果,不是事实
大多数页面的状态是这样来的:
后端数据 → 接口 → 前端渲染 → 你看到的文字
中间任何一环有缓存、有延迟、有批次同步,你看到的就不是事实,而是一段时间之前的事实。
这个平台的机制很具体:任务完成是实时记录的,但积分发放是按周期统一批处理的。于是就出现了:
| 观察位置 | 显示什么 | 准确度 |
|---|---|---|
| 任务页 | 「未完成」 | 滞后(可能滞后一整天) |
| 积分明细 | 次日凌晨才有一笔 | 滞后 4-6 小时 |
| 任务接口 | today_status: "done" |
实时、准确 |
三个地方说三种话。你要是只看页面,会得出「没做成」的结论,然后重复劳动。
二、怎么找到那个「说真话」的地方
方法比想象中简单:打开开发者工具,看页面在请求什么。
我这次抓到两个关键接口:
GET /api/growth/tasks → 任务状态、判定条件
GET /api/growth/bindings → 账号绑定状态
第一个接口的返回比页面详细得多:
{
"task_key": "gitcode-star",
"today_status": "done",
"completed_at": 1793802921062,
"evaluator": "external_check",
"orgs": ["harmony-practice-center"],
"repos": [],
"match": "any"
}
除了状态,它还暴露了判定规则:repos 为空 + match: any,意思是「这个组织下任意一个仓库都算」。
这条信息价值极大——页面上只写「Star 指定案例仓」,我一直以为要 Star 某个特定仓库,试了好几个才蒙对。看接口才发现是「任意」。
三、直接查接口比点页面快得多
验证状态时,与其刷新页面、滚动、找文字,不如直接请求:
await fetch('/api/growth/tasks', { credentials: 'include' })
.then(r => r.json())
.then(d => d.tasks.find(t => t.task_key === 'gitcode-star'))
注意两点:
credentials: 'include'——必须带上登录态,否则拿到的是登录页- 在页面上下文里执行,不要用 curl 从外部打——跨域和 Cookie 会让你怀疑人生
这样查一次不到 1 秒,比刷新页面快,而且不会被缓存骗。
四、但不要只看接口
反过来也有坑:接口返回 done,不代表积分就到了。
「任务完成」和「积分发放」是两个阶段。接口告诉你第一阶段过了,积分明细才告诉你第二阶段过了。两个都看,链条才完整。
我这周就是靠这个组合定位问题的:
- 接口说
done,积分明细没有 → 说明批次还没跑,等着 - 接口说
todo,但我确实操作过 → 说明判定没抓到信号,要查操作方式 - 两边都有 → 真完成了
五、这套方法能迁移到别的地方
不只是这个平台。任何有「任务/进度/状态」的系统,都可以这么验:
- 电商订单:页面显示「待发货」,接口可能已经出库
- 审核状态:前端「审核中」,接口可能已经有结论
- 同步进度:进度条卡在 99%,接口可能早就完成了
通用做法:找到那个渲染状态的接口,直接问它。
小结
这周最大的收获不是攒了多少分,而是记住了一个判断顺序:
页面 → 可能滞后; 接口 → 接近实时; 两者的差 → 就是系统的处理链路。
下次再遇到「我明明做了但没生效」,别急着重做。先打开 F12,看看真正记录这件事的那个接口怎么说。
十有八九,它早就告诉你了。
- 点赞
- 收藏
- 关注作者
评论(0)