抽屜的另一半:拿東西有防護,放東西沒有
第 4 堂的作業全班交得很好——三件事幾乎每個人都做到了。但盤點的時候發現一件很整齊的事:14 份作業裡有 10 份,在同一個地方漏掉同一件事,而且漏的方式一模一樣。這不是你們誰粗心,是 AI 寫這種程式時的固定習慣。這一頁把它講清楚,最後有一個要交的小作業。
第 4 堂的作業是三件事:跟團狀態留得住、抓台北天氣、接上全班共用清單。盤點結果——14 份作業裡 12 份三件事全做到,這在入門第 4 堂算相當好。
但同時也發現,10 份作業在同一個位置漏掉同一件事。當同一個錯誤出現在 10 個人身上,它就不是誰的疏忽,而是你們共同的助手(AI)有一個固定盲點。認出這種盲點,比修好這一個 bug 重要得多——這是「會用 AI 寫程式」和「被 AI 寫的程式坑」的分界線。
| 三件事全做到 | 12 人 / 14 人交件 |
| 寫入沒有防護(這頁要修的) | 10 人 |
| 寫入有防護 | 4 人:Jamie、Lettice、woola、Tina |
| 還有項目要補做 | 3 人:Tina、Sandy、Sally(見最後一段) |
先講你會看到什麼。想像有位同事用無痕視窗(或把瀏覽器隱私設定調得比較嚴)打開你的頁面:
| 他按下「我要跟」 | 畫面正常:人數 +1、按鈕變成「已跟團 ✓」 |
| 他重新整理 | 全部歸零。人數退回去、按鈕變回「我要跟」 |
| 他跟你說「你的頁面壞了」 | 你自己打開試——完全正常,怎麼試都對 |
回到第 4 堂的比喻:localStorage 是瀏覽器裡的抽屜。你們都做對了「從抽屜拿東西」這件事——而且都想到了「抽屜可能是空的」(第一次打開頁面時裡面什麼都沒有),所以拿的時候都加了防護。
漏掉的是另一半:把東西放進抽屜,也可能失敗。有些情況下這個抽屜是鎖住的——無痕模式、瀏覽器的隱私設定、或抽屜已經塞滿。這時候「放進去」這個動作會出錯,而如果沒有防護,程式就停在那一行,後面該做的事全部不會發生。
AI 在寫「拿」的時候,很容易想到「萬一抽屜是空的呢」——因為那是第一次打開頁面就會遇到的正常情況,它一定得處理。但寫「放」的時候,它預設放東西不會失敗——畢竟在它練習過的絕大多數情況裡,確實不會。
所以你拿到的程式碼會長成這樣:讀取那一段包著防護、寫入那一段光溜溜的。這種「一邊有一邊沒有」的不對稱,是你以後檢查 AI 產出時很好用的一個著眼點——不只是 localStorage,任何「有讀有寫」「有開有關」「有進有出」的成對動作,都值得問一句:另一半呢?
還有一個更根本的問題:存不進去的時候,畫面卻說存好了。與其讓使用者以為自己跟團成功、隔天中午發現沒被算進去,不如老實告訴他「這台裝置記不住,重整後會不見」。這叫「誠實的失敗」,比「安靜的失敗」好一百倍。
有兩份作業(Sybil、sam)的情況再進一步:他們把「存進抽屜」和「去外面抓資料」這兩件事包在同一層防護裡。結果是——
| 去抓天氣 | ✓ 成功,資料已經拿回來了 |
| 存進抽屜 | ✗ 失敗(抽屜鎖住) |
| 畫面顯示 | 「資料載入失敗」——但它明明載入成功了 |
這種錯誤會讓你抓錯方向:畫面說載入失敗,你就跑去查網路、查網址、懷疑天氣服務掛了,怎麼查都查不出問題——因為真正壞掉的是後面那個「存」的動作。
這件事最好的教材不在我這裡,在你同學的頁面上。這四位的寫入都有防護,寫法各有特色,建議直接打開來看:
| Jamie | 三件事全對、審查完全沒挑出問題。跟團人數用「原本的數字 + 我加了幾個」的算法,重複整理畫面也不會算歪 |
| Lettice | 三件事全對、審查完全沒挑出問題。抽到沒有評分的店家時,兩種情況(沒有這個欄位、欄位是空的)都擋掉了,不會跑出奇怪的星星 |
| woola | 把「抓資料 → 存抽屜 → 失敗就退回上次存的」抽成同一套流程給三個資料共用,連不上時畫面標「離線・上次抓取」而不是壞版 |
| Tina | 共用清單那項還沒做,但她已經做的兩處寫入都有防護,而且抓不到天氣時會退回顯示上次的資料並標「(快取)」——誠實的失敗就是這個意思 |
全班都要做(包含上面三位寫對的人——你們的任務是順手幫其他人看)。一張 issue + 一個 PR,照舊。
第 1 件 · 把抽屜的另一半補上
- 找出你頁面裡所有「存進 localStorage」的地方(跟團狀態、天氣、全班清單,通常三處)
- 每一處都要有防護:存不進去時,畫面不能壞掉、也不能騙人說存好了
- 「抓不到資料」和「抓到了但存不住」要顯示不同的訊息
- 自己驗一次:開一個無痕視窗打開你的頁面,按「我要跟」再重整——畫面不能壞掉
起手式 · 用自己的話改
我的頁面有三個地方會把資料存進 localStorage:跟團狀態、天氣、全班共用清單。 請幫我檢查這三個地方,把「寫入」也包上 try/catch(我現在只有「讀取」有包)。 另外請把「抓資料失敗」和「抓到了但存不進 localStorage」分成兩種情況處理: 存不進去的時候,畫面要照常顯示抓回來的資料,但要誠實告訴使用者 「這台裝置記不住,重新整理後會不見」,不要顯示成「載入失敗」。
請告訴我怎麼用無痕視窗測試我的頁面在「localStorage 不能寫入」時的行為, 以及我應該在開發者工具的哪個面板、看到什麼,才算確認防護真的有效。
第 2 件 · 把 PR 描述那三個問題答完
第 4 堂要求 PR 描述回答三個問題,盤點結果:14 份全部沒答完——「換裝置會不會不見」一個人都沒寫到。這題不是形式,它就是第 6 堂的入口:如果資料只活在你這台電腦的抽屜裡,那「同事看得到你跟團」這件事永遠做不到。
- 這個資料存在哪裡?(存在哪個抽屜、用什麼名字)
- 重整會不會不見?換裝置會不會不見?(兩個都要答,換裝置那題是重點)
- 我加的 fetch 資料來源需不需要密碼?(天氣和全班清單兩個都要答)
個別補做(只有這三位)
| Tina | 共用清單那項還沒做——你目前的清單是第 2 堂「抄」進來的固定清單,頁面上寫的「22 家店」現在實際已經是 35 家。改成 fetch 就會自動跟上 |
| Sandy | 共用清單有去抓、但抓回來的資料沒有接到畫面上——你顯示的總數和隨機推薦還是從自己那份固定清單來的。這個「有抓但沒接上」很難自己發現,值得看一次是怎麼回事 |
| Sally | 第 4 堂還沒交。三件事的起手式在第 4 堂頁面上都有,照著做就好;卡住隨時找我 |
講師 / 助教檢核重點
- 三個寫入點都有防護,無痕視窗實測畫面不壞、不假報成功
- 「抓不到」與「存不住」顯示不同訊息
- PR 描述三問答完,特別是「換裝置會不會不見」
- 學員能用自己的話說出「AI 只防一半」這個盲點