目录
一、为什么要使用promise封装
原生的axios书写是这样的:
axios({ url: 接口地址, method:请求方法, data:携带数据, }).then(res=>{ //请求接口成功的逻辑 }).catch(err=>{ //请求接口失败的逻辑 })
出现了这些问题:
(1)重复的地方特别多,显得代码不够优雅。
(2)后期一旦不使用axios,改用其它第三方访问后端插件,一个个文件去修改,累死宝宝了。
(3)若是axios.then()里面在嵌套多次访问后台请求,业务变得极其复杂,且代码不利于查看。
ES6中的promise横空出世,解决了上面的痛点。axios本身也是一个promise,promise的出现就是为了解决地狱回调的问题(地狱回调至在请求后台成功之后不断嵌套多次异步请求),这就是为什么使用promise封装axios请求。
二、如何封装以及使用
本项目使用的工具以及知识点: vue3+vite+axios+es6(promise)+es8(async,await),薄弱的地方建议先自学。
(1) vite搭建vue3项目控制台所需指令
npm init @vitejs/app
//输入项目名称,选择vue
cd ./项目名称
npm i //安装依赖
npm run dev //运行项目
npm install axios //安装axios依赖
(2)request.js 配置axios
import axios from 'axios' const baseURL='http://localhost:8888/lostFound' //后台接口的域名或者服务器地址 //请求拦截,会自动在axios请求后端的时候添加请求头,并将token添加到请求里面 const service =axios.interceptors.request.use(config => { if (localStorage.getItem('token')) { config.headers.token = localStorage.getItem('token'); } return config; }, error => { return Promise.reject(error) }) //响应拦截,将后端传回来的token放在localStorage缓存里 service.interceptors.response.use(response => { localStorage.setItem("token", response.headers.token); return response; }) export default service
(3)http.js中封装axios
import service from './request' //封装axios请求 const myRequest = options => { return new Promise((resolve, reject) => { service({ url: options.url, method: options.method || 'GET', data: options.data || {}, params: options.params || {} }).then(res => resolve(res)) //请求成功 .catch(err => reject(err)) //请求失败 }) } export default myRequest
(4)在App.vue使用
<script setup> import HelloWorld from './components/HelloWorld.vue' import { myRequest } from './utils/http' import { onMounted } from 'vue' /** * await后面跟一个promise,await可以省略很多.then的书写,让promise更加简洁优雅,await要在async函数体内使用 */ //get不携带参数获取数据 const getWithNoParameters = async () => { let res = await myRequest({ url: '/selectAllCategories'}) console.log('get不携带参数',res) } //get携带参数 const getWithParameters = async ()=>{ let params={ id:10 } let res=await myRequest({url:'/selectFoundDetailById',params}) console.log('get携带参数',res) } //post请求方式 const post = async()=>{ let formData=new FormData() formData.append('sno','1') formData.append('password','1') let res=await myRequest({url:'/login',method:'post',data:formData}) console.log('post:',res) } //生命周期钩子函数 onMounted(() => { getWithNoParameters() getWithParameters() post() }) </script> <template> <img alt="Vue logo" src="./assets/logo.png" /> <HelloWorld msg="Hello Vue 3 + Vite" /> </template> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
(4)运行结果:
(5)分析:
一个接口功能省下10行代码,一个项目假设有40个接口,你就能省下400行冗余代码了,感受到了精益求精的工匠精神。
三、拓展
//uniapp中也可以这样封装后端请求api export myRequest= options =>{ return new Promise((resolve,reject)=>{ uni.request({ url: options.url, method:options.method || 'GET', data: options.data || {}, success: res=>{ //请求后台成功 resolve(res) }, fail: err=>{ //请求后台失败 reject(err) } } }) }) } //微信小程序中也可以这样封装后端请求api export myRequest= options=>{ return new Promise((resolve,reject)=>{ wx.request({ url: options.url, method:options.method || 'GET', data: options.data || {}, success(res){ //请求后台成功 resolve(res) }, fail(err){ //请求后台失败 reject(err) } } }) }) }