好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

ES6 实战2-封装请求

ES6 + 实战 2 - 封装请求

1. 前言

在学习 Promise 相关小节时我们已经了解了 Promise 的基本 用法 和 Promise A + 规范,那么在实际项目中我们应该怎么去使用 Promise 来提高我们的效率,并且可以通过 Promise 去封装一些 异步方法 ,让我们在使用过程中更加得心应手。

本节我们将模拟 一个 真实的生产环境来对前端开发中最常见也是最重要的数据请求进行封装。通过使用封装 Promise 请求来学习 Promise 在实际项目当中是如何使用的。

2. 环境搭建

工欲善其事,必先利其器,在我们进入本节的学习前,我们需要先搭建我们的开发环境,在实际的项目中也是必须的。本节使用的是 Vue 脚手架 生成 的项目,不了解 Vue 的同学可以先去学习一下。在 vue.con fig .js 配置中,对 ajax 请求进行了 mock 操作,mock 的逻辑在 mock.con fig .js 文件 中,mock 的结果在 mock 文件 夹下对应的 json。

这样的配置在本节中就可以基本模拟真实的数据请求过程了,本节的源码在 GitHub 上。

3. 封装 ajax 请求

ajax 是前端用于发送接口请求的技术,它是异步的,需要等待结果返回 后执行

在发送 ajax 请求时,我们可能会这样去写。

  ajax  (  { 
  url :   ''  , 
  method :   ''  , 
  data :   {  }  , 
  p ara ms :   {  }  , 
  success :   function   ( res )   {  }  , 
  error :   function   ( err )   {  } 
 }  ) 
 

url: 接口请求地址; method: 接口请求 方法 ,如:get、post 等; data: 请求时使用 body 传输的数据,一般用于 post 请求中; p ara ms: 请求时使用 url 传递的数据,一般用于 get 请求中; success: 接口请求成功时的回调,参数为接口成功的返回值; error: 接口请求失败时的回调,参数为抛出异常时的 调用 栈等信息。

XMLHttpRequest 是浏览器提供的对象,用于进行 后台 与服务端的数据进行交互

实现 ajax

  function   ajax  ( options )   { 
   const   {  url ,  method ,  data ,  p ara ms ,  success ,  error  }   =  options ; 
   const  xhr  =   new   XMLHttpRequest  (  )  ; 

  xhr .  onreadystatechange   =   function   (  )   { 
     // readyState为4的时候已接收完毕 
     if   ( xhr . readyState  ===   )   { 
       // 状态码200表示成功 
       if   ( xhr . status  ===   )   { 
        console .  log  ( xhr . responseText )  ; 
        success .  call  (  this  ,  xhr . responseText )  ; 
       }   else   { 
        console .  log  ( xhr . status )  ; 
        error .  call  (  this  ,  xhr . status ) 
       } 
     } 
   }  ; 

   // get 请求 
   if   ( method  ===   'get'   ||  method  ===   'GET'  )   { 
     if   (  typeof  p ara ms  ===   'object'  )   { 
       // p ara ms拆解成字符串 
      p ara ms  =  Object .  keys  ( p ara ms )  .  map  (  function   ( key )   { 
         return   encodeURIComponent  ( key )   +   '='   +   encodeURIComponent  ( p ara ms [ key ]  )  ; 
       }  )  .  join  (  '&'  )  ; 
     } 
    url  =  p ara ms  ?    `  @H_646_ 403 @${ url@H_646_ 403 @}   ?  @H_646_ 403 @${ p ara ms@H_646_ 403 @}   `    :  url ; 
    xhr .  open  ( method ,  url ,   true  )  ; 
    xhr .  send  (  )  ; 
   } 

   // post 请求 
   if   ( method  ===   'post'   ||  method  ===   'POST'  )   { 
    xhr .  open  ( method ,  url ,   true  )  ; 
    xhr .  setRequestHeader  (  "Content-type"  ,   "application/json; charset=utf-8"  )  ; 
    xhr .  send  ( JSON .  stringify  ( p ara ms )  )  ; 
   } 
 } 
 

使用 promise 进行封装

  function   ajax  ( url ,  method ,  p ara ms )   { 
   return   new   Promise  (  ( resolve ,  reject )   =>   { 
     //  创建XML HttpRequest对象 
     const  xhr  =   new   XMLHttpRequest  (  )  ; 
     // 状态改变时的回调 
    xhr .  onreadystatechange   =   function   (  )   { 
       // readyState为4的时候已接收完毕 
       if   ( xhr . readyState  ===   )   { 
         // 状态码200表示成功 
         if   ( xhr . status  ===   )   { 
           resolve  ( xhr . responseText )  ; 
         }   else   { 
           reject  ( xhr . status )  ; 
         } 
       } 
     }  ; 
     // ... 
   }  )  ; 
 } 
 

4. axios 库封装

在真实的项目中会经常使用到 axios 这样的 ajax 请求的库,虽然可以直接使用,但是往往业务中会有很多接口请求的地方,而这么多的请求有些固定不变的,每个接口在请求时都需要,如:token,baseURL,timeout 等等,针对这样的场景,我们可以对 axios 库进行二次业务封装。对于接口不同的返回结果我们希望有 一个 全局的 提示 框,这里我们使用 element-ui 组件库搭配使用。封装后的 代码 如下:

  import  axios  from   'axios'  ; 
 import   {  baseURL  }   from   '@/con fig ' 

 class   Http   { 
     constructor  ( baseUrl )   { 
         this  . baseURL  =  baseURL ; 
         this  . timeout  =   ; 
     } 
     setInterceptor  ( instance )   { 
        instance . interceptors . request .  use  ( con fig   =>   { 
             return  con fig  ; 
         }  )  ; 
        instance . interceptors . response .  use  ( res  =>   { 
             if   ( res . status  ==   )   { 
                 return  Promise .  resolve  ( res . data )  ; 
             }   else   { 
                 return  Promise .  reject  ( res )  ; 
             } 
         }  ,  err  =>   { 
             return  Promise .  reject  ( err )  ; 
         }  )  ; 
     } 
     mergeOptions  ( options )   { 
         return   { 
            baseURL :   this  . baseURL , 
            timeout :   this  . timeout , 
             ... options
         } 
     } 
     request  ( options )   { 
         const  instance  =  axios .  create  (  )  ; 
         const  opts  =   this  .  mergeOptions  ( options )  ; 
         this  .  setInterceptor  ( instance )  ; 
         return   instance  ( opts )  ; 
     } 
     get  ( url ,  con fig   =   {  }  )   { 
         return   this  .  request  (  { 
            method :   'get'  , 
            url :  url , 
             ... con fig 
         }  ) 
     } 
     post  ( url ,  data )   { 
         return   this  .  request  (  { 
            method :   'post'  , 
            url , 
            data
         }  ) 
     } 
 } 
 export   default   new   Http  ; 
 

5. 小结

本节我们通过真实的业务场景触发,对原生的 ajax 请求做了 promise 封装,最后我们对真实的业务场景使用 axios 对业务二次封装,这样更好地复用业务逻辑,统一 增加 不同返回结果的 提示 。

应用 Promise 封装 Ajax 实践

查看更多关于ES6 实战2-封装请求的详细内容...

  阅读:40次

上一篇

下一篇

第1节:ES6+ 简介    第2节:ES6 环境配置    第3节:ES6+ let    第4节:ES6+ const    第5节:ES6+ 展开语法    第6节:ES6+ 剩余参数    第7节:ES6+ 解构赋值    第8节:ES6+ 模版字符串    第9节:ES6+ 箭头函数    第10节:ES6+ 数值扩展    第11节:ES6+ isFinite()&isNaN()    第12节:ES6+ Number 对象的方法    第13节:ES6+ Math 对象的扩展    第14节:ES6+ includes()    第15节:ES6+ 字符串的扩展    第16节:ES6+ startsWith()    第17节:ES6+ endsWith()    第18节:ES6+ repeat()    第19节:ES6+ padStart()    第20节:ES6+ padEnd()    第21节:ES6+ trim()    第22节:ES6+ Array.from()    第23节:ES6+ of()    第24节:ES6+ find()和findIndex()    第25节:ES6+ copyWithin()    第26节:ES6+ fill()    第27节:ES6+ isArray()    第28节:ES6+ 对象的扩展    第29节:ES6+ flat()    第30节:ES6+ 可选链操作符    第31节:ES6+ Object.is()    第32节:ES6+ Object.assign()    第33节:ES6+ Object.keys()    第34节:ES6+ Object.values()    第35节:ES6+ Object.entries()    第36节:ES6+ 数据结构扩展    第37节:ES6+ Set    第38节:ES6+ WeakSet    第39节:ES6+ Map    第40节:ES6+ WeakMap    第41节:ES6+ Symbol    第42节:ES6+ for...of    第43节:ES6+ 迭代协议    第44节:ES6+ 实现一个简版的 Promise    第45节:ES6+ Promise 基础    第46节:ES6+ Promise 进阶    第47节:ES6+ Generator 基础    第48节:ES6+ Generator 函数应用    第49节:ES6+ async/await    第50节:ES6+ Class 前置知识    第51节:ES6+ Class    第52节:ES6+ Proxy    第53节:ES6+ Reflect(一)    第54节:ES6+ Reflect(二)    第55节:ES6+ 模块化(一)    第56节:ES6+ 模块化(二)    第57节:ES6实战1-实现Vue3 reactive 源码    第58节:ES6实战2-实现 Vue3 effect 源码    第59节:ES6 实战2-封装请求    第60节:ES6+ 实战3-代码整洁之道    第61节:ES6 Map原理分析    第62节:ES6module语法加载importexport    第63节:ES6的循环与可迭代对象示例详解