前言
在日常工作中,我們經常接觸到表單驗證相關的功能。有些簡單的校驗(比如輸入要求爲手機號、郵箱、密碼的字符組合等)可以直接由前端進行判斷,但是有些複雜多變的判斷(比如校驗用戶名是否存在、特殊行政區提示等)就必鬚髮起請求由後端來驗證,然後前端根據後端返回的結果進行提示等處理(這裏稱該校驗的方式爲異步校驗)。
處理方式1:防抖
異步校驗(選擇框)存在以下一個問題:
- 我先選擇a
- 然後再選擇b
- b的請求先回來不需要提示
- a的請求後回來需要提示
這樣的話,提示就出錯了(最後選擇的是b,b是不需要提示的,而異步請求的結果是a的結果後回來,所以最終還是顯示了提示)。
這裏有一種方法,可以採用防抖技術,簡單來說就是當n秒內請求函數只會執行一次,如果n秒內事件再次被觸發,則重新計算時間,取消原來的請求。具體可以看:幫你徹底搞懂防抖和節流(附帶在React使用的一個例子)
處理方式2:採用標記
採用防抖並不是完美的,因爲防抖有個時間間隔N,如果網絡的請求速度非常慢的話(大大超過N),那麼在大於N的時間段內改變選擇框的值的話,那還是會發起多次的請求,而我們並不能保證多次請求返回結果的順序就是我們發起請求的順序,這樣還是可能會出錯。
第二種方法可以採用標記的方式:
- 在頁面的實例上添加一個
ID
屬性。 - 在處理輸入變化的函數內(
onChange()
)也定義一個變量id
,每次發起請求的時候,同時改變id
和ID
。 - 在請求的回調中對比
id
和ID
的值,如果它們不相等的話,則將請求結果拋棄,只取它們值相等的結果,這樣就能保證結果是最新發起請求返回回來的了(因爲每次發起請求時,id
和ID
同時更新,實例上的ID
是能代表最新一次發出的請求,而回調中的id
存的則是每次發出請求時的所生成的)。
僞代碼如下:
class Demo extends React.Component {
ID
...
onChange = (e) => {
let id = this.ID = Math.random()
api().then( res => {
if(this.ID !== id) {
return null
}
// 正常處理
})
}
}