窗外,是5月明媚的陽光,澄澈蔚藍的天空,有炮彈歡快地叫着飛過。50多年過去了,我依然如此清晰地記得。前端
在一些框架中發現會提供一個很實用的功能:攔截器(interceptor)。例如要實現這個需求:小程序每次獲取到定位後都存到 globalData
裏:git
wx.getLocation({
// ..
success(res) {
getApp().globalData.location = res
// ...
}
})
複製代碼
若是每一處使用 wx.getLocation
的地方都這麼寫也沒啥大問題,但總顯得不夠「智能」,一方面是多了重複代碼,另外一方面若是需求變更,獲取到定位後存到別的地方,那要改不少次。小程序
有了攔截器,能夠更優雅的實現它:api
intercept('getLocation', {
success(res) {
getApp().globalData.location = res
}
})
複製代碼
只要在一處定義如上的攔截器,其餘地方直接用 wx.getLocation
便可。那麼,如何實現上面的方式呢?數組
// utils/intercept.js
// 存儲攔截器定義
var interceptors = {}
function intercept(key, config) {
intercept[key] = config
}
export {
intercept,
interceptors
}
複製代碼
很簡單,暴露出 intercept
方法,定義一個存儲器也一併暴露出去。微信
要實現使用 wx.getLocation
自動應用攔截器,就必須基於原有方法從新定義它。框架
import { interceptors } from './intercept'
// 備份原有微信方法
var wxBackup = {}
[
'getLocation'
// 還能夠有不少其餘方法 ...
].forEach((key) => {
wxBackup[key] = wx[key]
wx[key] = (config) => {
if (interceptors[key]) {
// 備份業務代碼傳入的回調方法
var backup = {}
var interceptor = interceptors[key]
[
'success',
'fail',
'complete'
].forEach((k) => {
backup[k] = config[k]
config[k] = (res) => {
interceptor[k](res)
backup[k](res)
}
})
}
wxBackup[key](config)
}
})
複製代碼
固然,上述代碼用數組列出了全部可能被定義攔截器的微信函數,也可使用 Object.keys(wx)
通用處理。函數
上面的場景比較簡單,攔截器的應用還有更多場景。好比每次請求傳參帶上公參經緯度,接口返回的數據都會約定包裹在 object
中,請求回來須要取一遍。數據異常時還要針對錯誤碼作特定處理,就能夠很方便的用攔截器處理:組件化
intercept('request', {
data(data) {
var location = getApp().globalData.location
data.location = location.latitude + ',' + location.longitude
return data
},
success(res) {
if (res.code == 200) {
return res.object
} else {
if (res.code == 'xxx') {
// 登陸失效,從新登陸
// ....
}
}
}
})
複製代碼
注意,攔截器函數裏多了返回值,具體實現方法就很少寫,基於上述實現完善代碼便可。post
細心的讀者可能發現,咱們代理或者改造了不少微信提供的方法,有些開發者可能不喜歡這樣,但願保持原有代碼的純潔性。這要看團隊喜愛吧,基於此考慮,主要是不想定義太多新的方法或 api,儘可能以你們最爲熟悉的方式書寫代碼。
美團單車事業部(摩拜單車)誠招前端 / 小程序研發工程師,位置北京,有興趣能夠發簡歷到 zhangshibing@mobike.com 或者掃二維碼先加微信勾搭:)