在項目開發過程當中,代碼的封裝是頗有必要的,我以爲這是程序員進階的一個重要的技能,不會封裝代碼,你的代碼看起來亂的一批,基本上不能維護,像一次性塑料袋同樣,用完一次就失去了價值,這同時也會平白無故的增長項目的整體的代碼量,重複代碼的不斷疊加,誰也是這麼一步一步走過來的,可是我要學着去改變,主要是學習這其中的思想,從一個簡單的http請求的處理來看看如何進行代碼的封裝,讓你的代碼優雅。java
1、爛透了的代碼程序員
簡單說一下,這個場景是什麼,就是從服務器請求接口,將數據展現到頁面上,很簡單,也是最經常使用的,最基礎的功能,先看看一段最爛的代碼,不是說有多爛,只是說實現了功能,其餘的地方一無可取的,哈哈,下面是微信提供的請求數據的API小程序
1 wx.request({ 2 url: '接口的地址url', 3 data: { 4 names:'t-1' 5 }, 6 method: 'GET', 7 header: { 8 appkey:'your appkey' 9 }, 10 success: res=>{ 11 this.setData({ 12 topTheme:res.data[0] 13 }) 14 } 15 }) 16
我寫了挺長時間的代碼了,我發現一直以來,都是這麼寫的,沒有什麼封裝,擦!這段代碼自己沒有問題,功能也實現了,可是讓人看起來很不爽,後期的維護很費勁,並且隨着項目的開發進行,沒有用處的垃圾代碼會直線上升,這實際上是能夠優化的,看看有哪些地方是能夠進行優化的?segmentfault
2、不是那麼爛了微信小程序
優化能夠試着從下面幾點入手:設計模式
一、常量配置化api
像url地址、appkey這種是通用的,最起碼url的域名是通用的,能夠寫到一個單獨的配置文件中,這樣的話,很好維護,就像這樣子:服務器
1 const config = { 2 appkey:'your appkey', 3 apiBaseUrl:'通用的url地址' 4 } 5 // ES6的語法導出 6 export { 7 config 8 } 9 10 // 順便說一下,其餘的js文件如何導入呢? 11 import { 12 config 13 } from "文件的位置。。。";
二、業務處理的封裝微信
這個通常會放在單獨抽象出來的model層中,也就是項目中的model文件下的js文件中,咱們將拆分出來的模塊都抽象成一個個的js文件,具體的處理邏輯咱們在這裏處理,具體操做是在根目錄下面新建model文件夾,在model文件夾下新建theme.js文件,代碼具體以下:app
1 import { 2 config 3 }from '文件位置。。。' 4 5 // 關於主題的相關的業務的處理 6 class Theme { 7 // 獲取localhostA位置的主題 8 static getHomeLocationA(callback){ 9 wx.request({ 10 url: `${config.apiBaseUrl}theme/by/names`, 11 method: 'GET', 12 header: { 13 appkey: `${config.appkey}` 14 }, 15 data: { 16 names: 't-1' 17 }, 18 success: res => { 19 callback(res.data) 20 } 21 }) 22 } 23 } 24 // 別忘了導出 25 export { 26 Theme 27 }
在page中咱們就能這樣引用Theme類中的方法了:
1 Theme.getHomeLocationA(data =>{ 2 this.setData({ 3 themeA:data[0] 4 }) 5 })
看起來並無簡化,反而多增長了一個文件,哈哈,這麼想也沒什麼問題,不反駁,可是優化之路還在繼續,這還遠遠不夠呢!
3、代碼看起來整潔多了
在第二部分的基礎上,咱們進一步封裝代碼,將wx.request()進一步封裝成一個通用的工具類,進一步優化這個代碼!
一、封裝微信小程序的原生API
咱們在utils文件夾中新建http.js文件來作wx.request()的封裝,具體代碼以下:
1 // wx.request的封裝 2 import { 3 config 4 }from '文件位置。。。' 5 6 class Http{ 7 static request({url,data,callback,method='GET'}){ 8 wx.request({ 9 url: `${config.apiBaseUrl}${url}`, 10 method: method, 11 data: data, 12 header: { 13 appkey: `${config.appkey}` 14 }, 15 success: res => { 16 callback(res.data) 17 } 18 }) 19 } 20 } 21 // 別忘了導出 22 export { 23 Http 24 }
二、model層的調用
model層須要進行簡化,至於page頁面層,不用作修改
1 class Theme { 2 // 獲取localhostA位置的主題 3 static getHomeLocationA(func){ 4 Http.request({ 5 url:'theme/by/names', 6 data:{ 7 names:'t-1' 8 }, 9 callback:res=>{ 10 func(res) 11 } 12 }) 13 } 14 }
這個對異步請求的處理使用callback進行回調的用法基本上就封裝完成了,可是你要說這是終極解決方案,那確定不是,如何處理這個異步回調請求,仍是須要優化的,終極解決方案是利用ES6中async和await,這個的本質仍是利用Promise對象進行異步請求回調的處理
4、代碼有點優雅
代碼封裝的終極解決方案,雖然用了一段創造性的封裝小程序原生API,惋惜不是我創造的,七月老師寫的一段簡短的,頗有技巧性的代碼,如何利用async和await實現異步請求處理,看看代碼的實現:
一、繼續封裝小程序API
1 class Http { 2 static async request({ 3 url, 4 data, 5 method = 'GET' 6 }) { 7 // 這裏的關鍵是promisc方法,將原生API轉換成Promise對象 8 const res = await promisic(wx.request)({ 9 url: `${config.apiBaseUrl}${url}`, 10 method: method, 11 data: data, 12 header: { 13 appkey: `${config.appkey}` 14 } 15 }) 16 return res.data 17 } 18 }
二、model層調用Http類封裝的request方法
1 // 獲取localhostA位置的主題 2 static async getHomeLocationA(){ 3 return await Http.request({ 4 url:'theme/by/names', 5 data:{ 6 names:'t-1' 7 } 8 }) 9 }
三、page層調用model層getHomeLocationA方法
1 onLoad: async function(options) { 2 // 其實只有這一行的代碼,至於其餘代碼跟此次封裝不要緊了,必定要async和await一塊兒使用 3 const data = await Theme.getHomeLocationA() 4 this.setData({ 5 themeA:data[0] 6 }) 7 },
你以爲可能一次請求中代碼量並無少,反而層層的調用,使得代碼更多,可是若是是成百上千個請求呢,你難道每一次都像一種多寫的那樣,不斷重複寫wx.request請求???哈哈,真香警告
四、關鍵的代碼promisic()方法
1 const promisic = function(func) { 2 return function(params = {}) { 3 return new Promise((resolve, reject) => { 4 const args = Object.assign(params, { 5 success: (res) => { 6 resolve(res); 7 }, 8 fail: (error) => { 9 reject(error); 10 } 11 }); 12 func(args); 13 }); 14 }; 15 } 16 17 export { 18 promisic 19 }
至於這段代碼不作解釋,由於我也不是很懂,尷尬了,不過這裏用到的是設計模式中的代理模式,封裝了一下Promise對象,將原生的API的success和fail函數去執行Promise對象的resolve和reject函數,從而達到封裝成Promise對象的目的
5、終極項目結構
最終的結構通常會是這樣子:
跟着七月老師繼續努力!!!
七月老師課程連接:https://class.imooc.com/sale/javafullstack
async和await講解:http://www.javashuo.com/article/p-kywihefy-z.html