内容简介:我们在使用axios进行异步操作时,可能会遇到以下情况:axios.js设置一个cancelFlag作为标志符,默认为true,在请求拦截器时,判断如果cancelFlag为true,就可以发送请求,且将cancelFlag设为false。当cancelFlag为false,就取消请求。在响应拦截器中再将cancelFlag设为true。说明只用当一个请求发送且收到响应后,才可以发送另一个请求。这里存在的问题:cancelFlag是全局变量,这样多页面多个接口请求时,互相会有影响这里的解决办法就是在axi
我们在使用axios进行异步操作时,可能会遇到以下情况:
- 对一个按钮频繁点击,发送多次请求
-
axios的规范写法中:
axios.post(url, data).then(res=>{}).catch(err=>{}) 复制代码这里我们发现我们每一次写的时候,都需要写.catch(err=>{}),会造成代码的冗余
封装过程
拦截器科普
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
复制代码
取消请求处理方法科普
var CancelToken = axios.CancelToken;
var cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函数接收一个 cancel 函数作为参数
cancel = c;
})
});
// 取消请求
cancel();
复制代码
本文代码
axios.js
设置一个cancelFlag作为标志符,默认为true,在请求拦截器时,判断如果cancelFlag为true,就可以发送请求,且将cancelFlag设为false。当cancelFlag为false,就取消请求。在响应拦截器中再将cancelFlag设为true。说明只用当一个请求发送且收到响应后,才可以发送另一个请求。这里存在的问题:cancelFlag是全局变量,这样多页面多个接口请求时,互相会有影响这里的解决办法就是在axios.js中构建构造函数,这样可以让cancelFlag私有化,但是这样的方式会导致占有大量内存。参考同事写的代码,我觉得非常的有道理。而且比较简单。
版本一、
import Vue from 'vue'
import axios from 'axios'
import {Indicator} from 'mint-ui'
Vue.component(Indicator)
let CancelToken = axios.CancelToken //取消请求
let cancelFlag = true
//设置公共部分,请求头和超时时间
axios.defaults.headers = {
'X-Requested-With': 'XMLHttpRequest'
}
axios.defaults.timeout = 20000
//在请求拦截器时
axios.interceptors.request.use(config => {
if (cancelFlag) {
cancelFlag = false
Indicator.open()
} else {
cancelToken: new CancelToken (c => {
cancel = c
})
cancel()
}
return config
}, error => {
return Promise.reject(error)
})
复制代码
版本二、异步请求时,带上一个参数requestName。 这里一开始的疑惑是,当请求a带上参数requestName后,发送多次请求,判断axios[requestName]和axios[requestName].cancel存在时,会做取消处理。那发送成功后,再点击时,axios[requestName]和axios[requestName].cancel还是会存在啊。这样还是会执行axios[requestName].cancel()。这里是因为当上一次请求发送成功后,其axios[requestName].cancel这个方法已经失效,即使执行了这个方法也不起作用。axios[requestName].cancel的值永远是上一次的请求的取消回调。当上一次请求成功后,该回调会失效。
axios.interceptors.request.use(config => {
let requestName = config.data.requestName
if (requestName) {
if (axios[requestName] && axios[requestName].cancel) {
axios[requestName].cancel()
}
config.cancelToken = new CancelToken (c => {
axios[requestName] = {}
axios[requestName].cancel = c
})
}
return config
}, error => {
return Promise.reject(error)
})
复制代码
响应的错误处理封装
axios.interceptors.response.use(config => {
Indicator.close()
return config
}, error => {
cancelFlag = true
Indicator.close()
if (error && error.response) {
switch (error.response.status) {
case 400:
error.message = '错误请求'
break;
case 401:
error.message = '未授权,请重新登录'
break;
case 403:
error.message = '拒绝访问'
break;
case 404:
error.message = '请求错误,未找到该资源'
break;
case 405:
error.message = '请求方法未允许'
break;
case 408:
error.message = '请求超时'
break;
case 500:
error.message = '服务器端出错'
break;
case 501:
error.message = '网络未实现'
break;
case 502:
error.message = '网络错误'
break;
case 503:
error.message = '服务不可用'
break;
case 504:
error.message = '网络超时'
break;
case 505:
error.message = 'http版本不支持该请求'
break;
default:
error.message = `连接错误${error.response.status}`
}
} else {
error.message = "连接到服务器失败"
}
return Promise.reject(error.message)
})
复制代码
http.js(封装了post和get请求)
在axios.js文件里对响应拦截器做了判断error.response.status的值的处理,根据不同的状态码返回不同的error说明。在http.js文件里post和get函数的参数为三个,第三个参数error就是出现错误时的文案。使用该api可以自己设置该文案,如果不传这个参数,那么就返回axios.js设置的error文案
import Vue from 'vue'
import axios from './axios'
import 'mint-ui/lib/style.css';
import {Toast} from 'mint-ui'
Vue.component(Toast)
export function post (url, data, error) {
return new Promise((resolve, reject) => {
axios.post(url, data).then(res => {
resolve(res)
}, err => {
err = error ? error : err
Toast({
message: err,
duration: 500
})
})
})
}
export function get (url, data, error) {
return new Promise((resolve, reject) => {
axios.post(url, {
data: data
}).then(res => {
resolve(res)
}, err => {
err = error ? error : err
Toast({
message: err,
duration: 500
})
})
})
}
复制代码
使用
1)在main.js引入文件
import axios from '../utils/axios.js'
import {post, get} from '../utils/http.js'
Vue.prototype.$axios = axios
Vue.prototype.$post = post
Vue.prototype.$get = get
复制代码
2)组件中使用
this.$post('/api/saveInfo', {
value: this.value
}, '请求失败啦~~~').then(res => {
// alert(res.data)
})
复制代码
代码: github地址链接
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Flutter学习指南:封装 API 插件
- 【机器学习02】Python 手写 sklearn kNN 封装算法
- Hacker News热议:封装包那么多,程序员还用学习算法吗?
- 封装JDBC—非框架开发必备的封装类
- SpringBlade 2.3.2 发布,增加 OSS 封装及单元测试封装
- SpringBlade 2.3.2 发布,增加 OSS 封装及单元测试封装
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Writing Windows VxDs and Device Drivers, Second Edition
Karen Hazzah / CMP / 1996-01-12 / USD 54.95
Software developer and author Karen Hazzah expands her original treatise on device drivers in the second edition of "Writing Windows VxDs and Device Drivers." The book and companion disk include the a......一起来看看 《Writing Windows VxDs and Device Drivers, Second Edition》 这本书的介绍吧!