From e153064d87d77ddf62c87b5734223e008406d144 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Thu, 6 Aug 2026 03:38:24 -0600 Subject: [PATCH] fix(reaction): guard toggle against out-of-order responses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用请求代号确保只有最新一次点击的响应会写回本地状态,乐观更新的 回滚路径同样受保护,避免旧请求晚到覆盖新状态。不引入防抖、不禁用按钮。 Co-Authored-By: Claude Opus 5 --- src/oj/problem/components/ProblemReaction.vue | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/oj/problem/components/ProblemReaction.vue b/src/oj/problem/components/ProblemReaction.vue index 11fe849..376771d 100644 --- a/src/oj/problem/components/ProblemReaction.vue +++ b/src/oj/problem/components/ProblemReaction.vue @@ -57,6 +57,10 @@ function tooltipOf(key: ReactionKey, label: string) { return label } +// 连续点击不做防抖、不禁用按钮,靠请求代号保证后到的旧响应不会覆盖新状态: +// 每次点击自增一次,只有仍是最新请求时才把结果写回本地状态 +let requestSeq = 0 + async function toggle(key: ReactionKey) { if (!problem.value) return const prevMine = [...mine.value] @@ -69,11 +73,14 @@ async function toggle(key: ReactionKey) { mine.value = next if (counts.value) counts.value[key] += selected ? -1 : 1 + const seq = ++requestSeq try { const res = await setReaction(problem.value.id, next) + if (seq !== requestSeq) return mine.value = res.data.mine counts.value = res.data.counts } catch { + if (seq !== requestSeq) return mine.value = prevMine counts.value = prevCounts message.error("操作失败,请重试")