zoukankan      html  css  js  c++  java
  • 全栈之路-杂篇-前端Http请求封装优化

      在项目开发过程中,代码的封装是很有必要的,我觉得这是程序员进阶的一个重要的技能,不会封装代码,你的代码看起来乱的一批,基本上不能维护,像一次性塑料袋一样,用完一次就失去了价值,这同时也会无缘无故的增加项目的总体的代码量,重复代码的不断叠加,谁也是这么一步一步走过来的,但是我要学着去改变,主要是学习这其中的思想,从一个简单的http请求的处理来看看如何进行代码的封装,让你的代码优雅。

    一、烂透了的代码

    简单说一下,这个场景是什么,就是从服务器请求接口,将数据展示到页面上,很简单,也是最常用的,最基础的功能,先看看一段最烂的代码,不是说有多烂,只是说实现了功能,其他的地方一无是处的,哈哈,下面是微信提供的请求数据的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     

    我写了挺长时间的代码了,我发现一直以来,都是这么写的,没有什么封装,擦!这段代码本身没有问题,功能也实现了,但是让人看起来很不爽,后期的维护很费劲,而且随着项目的开发进行,没有用处的垃圾代码会直线上升,这其实是可以优化的,看看有哪些地方是可以进行优化的?

    二、不是那么烂了

    优化可以试着从下面几点入手:

    1、常量配置化

    像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 "文件的位置。。。";

    2、业务处理的封装

    这个一般会放在单独抽象出来的model层中,也就是项目中的model文件下的js文件中,我们将拆分出来的模块都抽象成一个个的js文件,具体的处理逻辑我们在这里处理,具体操作是在根目录下面新建model文件夹,在model文件夹下新建theme.js文件,代码具体如下:

     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 })

    看起来并没有简化,反而多增加了一个文件,哈哈,这么想也没什么问题,不反驳,但是优化之路还在继续,这还远远不够呢!

    三、代码看起来整洁多了

    在第二部分的基础上,我们进一步封装代码,将wx.request()进一步封装成一个通用的工具类,进一步优化这个代码!

    1、封装微信小程序的原生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 }

    2、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对象进行异步请求回调的处理

    四、代码有点优雅

    代码封装的终极解决方案,虽然用了一段创造性的封装小程序原生API,可惜不是我创造的,七月老师写的一段简短的,很有技巧性的代码,如何利用async和await实现异步请求处理,看看代码的实现:

    1、继续封装小程序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 }

    2、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   }

    3、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请求???哈哈,真香警告

    4、关键的代码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对象的目的

    五、终极项目结构

    最终的结构一般会是这样子:

    跟着七月老师继续努力!!!

    七月老师课程链接:https://class.imooc.com/sale/javafullstack

    async和await讲解:https://segmentfault.com/a/1190000011526612

  • 相关阅读:
    129 01 Android 零基础入门 02 Java面向对象 06 Java单例模式 03 饿汉模式 VS 懒汉模式 02 懒汉式的代码实现
    128 01 Android 零基础入门 02 Java面向对象 06 Java单例模式 03 饿汉模式 VS 懒汉模式 01 饿汉式的代码实现
    127 01 Android 零基础入门 02 Java面向对象 06 Java单例模式 02 单例模式概述 01 单例模式的定义和作用
    126 01 Android 零基础入门 02 Java面向对象 06 Java单例模式 01 设计模式概述 01 设计模式简介
    125 01 Android 零基础入门 02 Java面向对象 05 Java继承(下)05 Java继承(下)总结 01 Java继承(下)知识点总结
    leetcode-----121. 买卖股票的最佳时机
    leetcode-----104. 二叉树的最大深度
    Json串的字段如果和类中字段不一致,如何映射、转换?
    Mybatis-Plus的Service方法使用 之 泛型方法default <V> List<V> listObjs(Function<? super Object, V> mapper)
    模糊查询
  • 原文地址:https://www.cnblogs.com/ssh-html/p/11726278.html
Copyright © 2011-2022 走看看