全栈之路-杂篇-前端代码封装优化

  在项目开发过程当中,代码的封装是颇有必要的,我以为这是程序员进阶的一个重要的技能,不会封装代码,你的代码看起来乱的一批,基本上不能维护,像一次性塑料袋同样,用完一次就失去了价值,这同时也会平白无故的增长项目的整体的代码量,重复代码的不断叠加,谁也是这么一步一步走过来的,可是我要学着去改变,主要是学习这其中的思想,从一个简单的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

相关文章
相关标签/搜索