在和後端打交道時,前端同學必須遵循一個原則:不要相信後端。這裏不是說你們的基友關係,私下可以是好朋友,但是一定不要信任他們返回來的資料格式。
有經驗的前端同學都知道,不是所有後端都會嚴格按照API來返回資料的,特別是空值的情況,比如本來我們期望後端返回一個空陣列,結果他們返回一個null,本來我們期望返回一個字串,結果他們啥都沒有返回,如果前端不加相容,程式碼就很容易崩潰。
let res = { data: { items: null //預期是陣列,結果返回了null } } //下面這段程式碼直接崩潰了 res.data.items.forEach(item =>{ }) //這裏也崩潰了 let tags = res.data.tags.split(',');
上面這個示例,我們內心其實認定了 res.data.items一定存在,且是Array型別,而res.data.tags一定存在且是String型別,不過可惜後端返回的格式並不對,而如果要寫出非常相容的程式碼也很麻煩。
import _ from 'lodash'; let res = { data: { items: null } } //嘗試寫出相容的程式碼 (_.get(res, 'data.items') || []).forEach(item =>{ })
一般情況下我都是像上面這麼處理的,透過lodash.get方法安全取值,然後如果沒有值時就給它賦予一個空陣列,不過這仍然有風險,萬一 _.get(res, 'data.items') 是物件格式豈不又崩潰了,所以這樣寫還不夠安全,但是如果各種情況都考慮,程式碼就太複雜了。
import _ from 'lodash'; let res = { data: { items: null } } //嘗試寫出相容的程式碼 let items = _.get(res, 'data.items'); if(!Array.isArray(items)){ items = [] } items.forEach(item =>{ })
這太複雜了,要是到處都寫這樣的程式碼那就煩死了,也很不優雅,能不能封裝一個方法,既能安全取值,又保證返回的資料格式一定是我們想要的。基於這個思路就想著擴充套件幾個lodash的方法,lodash支援透過 mixin擴充套件方法。擴充套件以下2個方法:
promiseArray(obj, path): 從obj的path中安全取值,並確保返回的一定是Array格式
promiseString(obj, path): 從obj的path中安全取值 ,並確保返回的一定是String格式
import _ from 'lodash'; //擴充套件lodash方法 _.mixin({ promiseArray: function (obj, path){ let value = _.get(obj, path); return Array.isArray(value) ? value : [] }, promiseString: function (obj, path){ let value = _.get(obj, path); return typeof value === 'string' ? value : '' }, }) let res = { data: { items: null } } //業務程式碼中這麼使用 //放心大膽地呼叫陣列方法吧 _.promiseArray(res, 'data,items').forEach(item =>{ }) let tags = _.promiseString(res, 'data.tags').split(',');
怎麼樣,是不是特別的優雅,而且也僅僅只是簡簡單單的封裝了一下,毫無技術含量,相信大家都可以自行實現。好了,有沒有人能封裝下 promiseObject方法~~