描述
這周在做一個簡單的電商項目,遇到了一個問題:用戶在點擊了商品收藏按鈕后,數(shù)據(jù)庫里添加了2條記錄,它們除了主鍵Id外其他字段都相同。
實現(xiàn)情況
添加收藏這個功能的實現(xiàn)方式是這個樣子的:后端有一個控制器來處理來自網(wǎng)頁的異步POST請求,然后返回JSON來告知是否成功。數(shù)據(jù)庫是一個簡單的用戶與商品的關(guān)系表??刂破髦幸呀?jīng)做了是否重復(fù)添加的判斷。
分析與解決
首先,第一反應(yīng)是檢查控制器的判斷條件是否寫錯了,結(jié)果是并沒有。
之后,思考了一陣,查看了收藏操作的網(wǎng)絡(luò)請求,結(jié)果發(fā)現(xiàn)這個點擊事件發(fā)送了兩次POST請求。這樣就暫時算搞清楚了問題的原因,即并發(fā)問題??紤]到這個系統(tǒng)應(yīng)該對并發(fā)的要求并不高,后端暫時不需要調(diào)整。那么,接下來這個問題就簡化為了另一個問題——為什么一次點擊事件觸發(fā)了兩次POST請求。
檢查了js代碼,這個事件綁定的方法沒有寫錯。preventdefault,發(fā)起異步post請求,處理異步請求返回結(jié)果。
我對前端不太熟,請教了公司里的老司機。他說一般兩個原因:
事件重復(fù)綁定。檢查了一圈,并沒有。
其實和1是相同的,只是表現(xiàn)不太一樣,即綁定事件所在js外部文件被重復(fù)引入。由于項目不大,js文件都是在render頁面中手工引入的。果然,該文件在layout模板和當(dāng)前頁面中各被引用一次,因此才出現(xiàn)了這個問題。
總結(jié)
排查bug和寫代碼也是一樣的,大事化小,小事化無。無限可能的情況,按順序排查,進(jìn)而將問題轉(zhuǎn)化為更小的問題。這和代碼的抽象是同樣的東西。
注意js文件的引入以及事件的綁定情況。