← ClaudeAtlas

async-task-uilisted

背景任務與多工介面紀律——任何「使用者按下開始、系統在背景長時間工作」的介面(報表產出、批次處理、匯入匯出、長查詢、AI 生成)怎麼做到不騙人、不失控、不還魂。用於設計或修改任務型 UI:狀態機先於介面、終態不可逆、完成未領取進收件匣不自動佔版面、視圖與任務分離(伺服器為真相源)、送出必冪等、並行語意顯性化、測試必含髒環境。背景任務 UI 的失敗模式極其固定:重複送出、進度假死、重整丟任務、歷史任務還魂、完成了卻找不到結果——全部有標準解。
poloplay0114/hard-won-claude-skills · ★ 0 · AI & Automation · score 67
Install: claude install-skill poloplay0114/hard-won-claude-skills
# 背景任務與多工介面紀律(Async Task UI) ## 什麼時候用 任何時候介面上出現「開始」按鈕、而工作要跑超過幾秒:報表/文件產出、批次匯入、長時間查詢、 AI 生成、檔案轉換。這類介面的物理是固定的:**HTTP 是無狀態的、前端是會死的(重整/關頁/斷線)、 使用者是會亂點的**——而任務必須活得比這三者都久。業界對此有一套高度一致的標準骨架 (送出→立即回任務 ID→背景執行→狀態端點輪詢→終態→領取結果);這份技能是那套骨架 加上真實踩雷換來的鐵則。失敗模式極其固定,標準解也是——不需要發明,需要的是不偏離。 --- ## 核心法則 ### 法則 1:狀態機先於介面——先定生死,再畫畫面 動手寫任何任務 UI 元件之前,先把任務狀態機定下來:最小集 `queued(排隊)→ running(執行中)→ succeeded / failed / cancelled(終態)`, 外加正交的 `delivered(已領取)`旗標。 - **狀態轉移寫成一張表入碼**(哪個狀態能到哪個狀態),禁止散落在各處的 if; 轉移表配測試——非法轉移會吠。 - 進度百分比、預估時間都是裝飾,**狀態才是骨架**;先有誠實的狀態,才配有進度條 (給不出誠實的百分比就別給,狀態文字比假進度可信)。 - 沒先定狀態機就寫介面=每個元件各自發明任務的生死,之後每顆 bug 都是「兩處對任務 狀態的理解不一致」。 ### 法則 2:終態不可逆——完成的任務進收件匣,絕不還魂 終態(succeeded/failed/cancelled)是單行道:**任何自動機制(重連、輪詢、恢復) 永不把終態任務重新開成工作視圖**。 - 完成而未領取(succeeded 且未 delivered)的任務 → **收件匣/任務中心**:被動列出, 使用者點了才開;絕不自動佔用分頁/版面。 - 歷史殘留任務(幾天前的、測試留下的)一律歸收件匣;「載入時把所有找得到的任務 都開成分頁」是本技能最經典的案發現場(見下)。 - 收件匣同時解掉「任務完成時使用者不在場」的交付問題——結果有家可歸,不必賭 使用者的視窗還開著。 ### 法則 3:視圖與���務分離——伺服器是真相源,前端只是望遠鏡 任務的生死存亡**絕不繫於任何視窗/分頁/前端物件的存活**: - 送出後任務屬於伺服器;前端拿 task_id 輪詢狀態端點——關頁、重整、斷線,任務照跑。 - **重整=望遠鏡重新對焦**:載入時查詢「進行中/排隊中」任務、把視圖掛回去; 不是任務重生、更不是任務死亡。 - 重連機制只認**非終態**(法則 2);且「掛回」=更新既有視圖或掛回既有容器, **絕不因輪詢撈到東西就開新版面**——視圖的誕生只有兩個合法來源:使用者動作、 載入時掛回真正在跑的任務。 - 多視圖(多分頁)時,每個視圖各持自己的狀態容器(per-tab context), 禁全域單例——全域狀態跨 await 交換必有 re-entrancy 撞況。 ### 法則 4:冪等是送出的義務——連點、重試、重載都不得生出第二份工作 背景工作天生會被觸發多次(連點、網路重試、頁面重載後再按)——**同一份邏輯工作, 跑幾次都只能算一次**: - 前端:送出即禁用按鈕/去抖(第一道,擋手速)。 - 服務端:冪等鍵(內容鍵或請求鍵)——同鍵重複送達=回同一個 task_id,不開新任務 (第二道,擋一切前端擋不住的)。兩道都要,只有前端的=沒有。 -