全棧之路-雜篇-前端代碼封裝優化

  在項目開發過程當中,代碼的封裝是頗有必要的,我以爲這是程序員進階的一個重要的技能,不會封裝代碼,你的代碼看起來亂的一批,基本上不能維護,像一次性塑料袋同樣,用完一次就失去了價值,這同時也會平白無故的增長項目的整體的代碼量,重複代碼的不斷疊加,誰也是這麼一步一步走過來的,可是我要學着去改變,主要是學習這其中的思想,從一個簡單的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

相關文章
相關標籤/搜索