后端返回null,前端怎么處理?數據容錯——不用過分相信外部數據


場景

我們在開發過程當中,總是會遇到因為數據原因,導致使用數組方法或者獲取對象屬性的時候報錯。

xxx is not fuction

Cannot read property xxxx of undefined

因為這些錯誤,會導致直接頁面打不開,所以我們一般會做一些容錯處理,從而讓頁面可以正常打開。例如:&& 、三元運算符,甚至有時會看到 if 語句來處理。

常見方式

 1 // response 是來自接口的數據
 2 const response = { 
 3     code: 200, 
 4     msg: 'message', 
 5     data: { 
 6         total: 100, 
 7         page: 1, 
 8         pageSize: 10, 
 9         content: [] 
10     }
11 }
12 
13 const goodsList = response.data.content.forEach(() => {})
14 const total = response.data.total

 

為了保證取data、content屬性和使用forEach不報錯,可能會這樣做

1 const goodsList = response.data && response.data.content && response.data.content.forEach(() => {})
2 const total =  response.data && response.data.total

 

這樣就初步完成了數據容錯,但是代碼過於冗余可讀性差,而且 total 的值還會可能變成 Boolean 類型。

簡單改進

只需要簡單的兩個處理,一個是解構,一個是給默認值

1 const { data = {} } = response
2 const { constent = [], total = [] } = data
3 goodsList.forEach(() => {})

 

解構是非常有必要的,增加代碼可讀性和扁平化數據

不過,但這里又有了新的問題。這個時候如果我得到數據如下的樣子:

1 const response = {
2     data: null
3 }

 

那么解構就會報錯 Cannot destructure property content of 'undefined' or 'null'

默認值生效的條件是,對象的屬性值嚴格等於undefined

上面代碼中,屬性data等於null,因為null與undefined不嚴格相等,所以是個有效的賦值,導致默認值 {} 不會生效。實際就成了如下的樣子:

1 const { constent = [], total = [] } = null 

 

因此我們得保證拿到的數據不能存在null,不然上面的代碼就沒意義了。

進一步改進

你可能在想和后端約定好不返回 null 就好了

但是不能過分相信外部數據,包括約定之后的

這種情況其實可以在封裝axios 或者fetch的時候,在里面添加一個過濾的函數,把從接口拿到的數據過濾一下,過濾掉值為 null 的數據,或者是把為 null 的數據重新賦值為 undefined。

下面是過濾數據的函數

 1 // 把獲取到的數據過濾一遍
 2 const replaceNull = (obj) => {
 3     for (let key in obj) {
 4         switch (Object.prototype.toString.call(obj[key]).slice(8, -1)) {
 5             case 'Object': 
 6                 replaceNull(obj[key])
 7                 break;
 8             case 'Array': 
 9                 for (let i = 0; i < obj[key].length; i++){
10                     replaceNull(obj[key][i])
11                 }
12                 break;
13             default:
14                 if (obj[key] === null) obj[key] = undefined;
15         }
16     }
17 }

 

過濾之后,這個時候這種寫法就沒問題了

1 const { data = {} } = response
2 const { constent = [], total = [] } = data
3 goodsList.forEach(() => {})

 

當然如果你們有node作為中間層,前端視圖層是可以放心的使用解構默認值的,比如 graphQl 這種。

結束語

前端數據容錯處理是必須的,不能期待外部數據的格式就是自己想要的。不知道大家平時都是怎么處理的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM