无论你成为谁,无论你把自己变成了什么,那就是你本来的样子。 ----《你当像鸟,飞往你的山》
请欣赏我的猫

在作为一颗螺丝钉,不停地写各种业务代码的时候,请求接口是难免的。这时候就会遇到封装HTTP请求的时候。在先人们遗留下的祖传代码中,总会遇到不同形式的封装。此时,我不禁对各式各样的封装产生了疑问,到底哪种才是最简洁多效的。于是,萌新的我在努力搜寻各大神贴之后,觉得写一个自己的总结,加深记忆。
想到前端发送http请求,最先想到的大都是axios。
Promise based HTTP client for the browser and node.js
axios用法----以get请求为例
import axios from "axios";
export default {
data() {
return {
url: "" //your url
};
},
created() {
console.log(this.get());
console.log("created---------");
},
methods: {
get() {
return axios
.get(this.url)
.then(res => {
console.log("请求接口成功");
})
.catch(err => {
console.log(err);
});
}
}
控制台打印的内容是:

Promise: 提到promise自然而然地就会跟异步联系到一起。promise的出现解决了异步执行中回调地域的出现。then方法返回的仍然是一个Promise对象,因此它可以以队列的形式解决函数多重回调的问题。
刚开始写前端的时候,接手了公司的一个项目,祖传代码中封装的http文件里层层的promise看的我云里雾里,只觉得如此复杂牛逼,一点也不敢造次改动。可是,既然axios本身就是返回的是个Promise,那为啥还要在axios请求外包上一层甚至多层的promise呢。是不是有什么玄机是我没有参透,于是就找到了下面一个问题。


这里穿插一下浏览器执行代码顺序。
- 先将主任务从上至下执行
- 再执行任务队列。任务队列中先执行微任务,再执行宏任务。
- 微任务: 语言标准提供的叫微任务。如ES6提供的Promise 、process.nextTick
- 宏任务:宿主环境提供的叫宏任务,如 定时器(比如:setTimeout)、事件(比如:onclick)、整体代码script
test(){
setTimeout(() => {
console.log("setTimeout"); //宏任务
});
new Promise((res, rej) => {
res();
}).then(res => {
console.log("new promise"); //微任务
});
console.log("script"); //主流程
}
test();
执行结果:

有的时候,我们需要再拿到接口返回的数据(微任务)后,再进行其他的逻辑(主流程)处理。自Promise之后又有了Generator(生成器) 以及它的语法糖--async。
- Generator(生成器)是一类特殊的函数,由function*定义,并且,除了return语句,还可以用yield返回多次
- Generator最大的特点就是可以交出函数的执行权(即暂停执行)
- Promise和Generator最大的不同是,Promise只在Promise体内进行异步执行,不会阻止主任务队列。而Generator是阻断主任务队列的执行,直到异步代码执行完毕后再继续主任务队列的执行。
async test(){
setTimeout(() => {
console.log("setTimeout"); //宏任务
});
await new Promise((res, rej) => {
res();
}).then(res => {
console.log("new promise"); //微任务
});
console.log("script"); //主流程
}
test();
执行结果如下:

以上
本该到这里就结束了,想了想还是斗胆放一下封装的http请求---手动狗头
vue-cli3
http/setBaseUrl.js
//根据环境区分域名
let rootUrl,imgUrl;
switch(process.env.NODE_ENV){
case 'dev':
rootUrl='http://test.mytest.cn';
imgUrl:'http://test.oss-cn-shanghai.sliyun.com/';
break;
case 'pre':
rootUrl='http://test.mytest.cn';
imgUrl:'http://test.oss-cn-shanghai.sliyun.com/';
break;
case 'pro':
rootUrl='http://test.mytest.cn';
imgUrl:'http://test.oss-cn-shanghai.sliyun.com/';
break;
default:break;
}
export {rootUrl,imgUrl}
http/index.js
//可添加拦截器,请求错误处理等
import axios feom 'axios'
export default class HTTP{
get(){
return axios.get(url).then(response => {
if(response.status === 200){
return response.data
}
}.catch(err => {
throw err
})
)
}
post(params){
return axios.post(url,params).then(response => {
if(response.status === 200){
return response.data
}
}).catch((err => {
throw err
}))
}
}
http/api.js
//封装api
import Http from './index'
import {rootUrl,imgUrl} from './setBaseUrl'
const apiForLogin = new (class extends Http{
constructore(){
super()
}
login(url){
let
return this.get(`${rootUrl}${url}`)
}
})
export default apiForLogin
login.vue
//调用接口
import apiForLogin from '@/http/api.js'
export dafult{
data(){
return {
url:'/login'
}
},
methods(){
async login({name,password}){
let res = await apiForLogin.login(`${url}?name=${name}&psw=${password}`)
res.status===200 && this.$router.push('/index')
}
}
}
以上以上