熟悉公司项目,摸索到 axios 的封装的时候,发现了一些以前没接触过的东西 。
1. 使用场景
大致的场景是,有一个下拉框,点击不同的选项会向服务器发送同一个请求但携带不同的参数,响应回来的数据在一个折线图里面展示,然后我就发现了 cancelToken
这个小东西。
项目里面取消的是上一次的请求,擦,前人写的代码还蛮有意思的,上面需求实现的思路是,给下拉框双向绑定一个值,然后监听这个值,变化了就发送请求,然后如果当前请求还没完成,用户又发送一个新的请求,就取消上次请求,保证数据是用户想要的最新的。
2. cancelToken
首先介绍一下 cancelToken
,在官网的文档中给了两个栗子,我给大概说明一下
2.1 使用 source
函数
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});
axios.post('/user/12345', {
name: 'new name'
}, {
cancelToken: source.token
})
// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');
复制代码
axios
实例上边会有 CancelToken
属性,该属性会有一个 source
方法,该方法返回一个对象,上边代码定义为了 source
。在请求中,第二个参数中的 cancelToken
字段用 source.token
标记,这样你执行 source.cancel
方法的时候,被标记的请求就取消了。所以上边的 post
和 get
请求都会取消。
2.2 使用 CancelToken
构造函数
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函数接收一个 cancel 函数作为参数
cancel = c;
})
});
// cancel the request
cancel();
复制代码
通过传递一个 executor
的函数给 axios.CancelToken
的构造函数,executor
就能接收到一个参数,这个参数是一个函数,执行他就能终止请求。
2.3 和防抖的区别
按照我的理解,实现的目的都是差不多的吧,都有防止请求数据混淆冲突,取消重复请求,保证数据最新,提高性能的特点,不同的是应用场景的不同。防抖都知道最经典的就是提交按钮,给下拉框写防抖说实话,不太好写吧。防抖也可以用 cancelToken
来中断请求。
3. XMLHttpRequest
也是看大佬们的博客和大家的讨论才知道,ajax不算是一种技术或者工具,是能说是一种概念,技术方案,特点就是能够局部刷新页面,其中的重点就是 XMLHttpRequest
原生的是这么用的
xhr = new XMLHttpRequest();
xhr.open("GET","url",true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.onreadystatechange = function(){
//请求成功时
if(xhr.readyState == 4 && xhr.status == 200){
alert(xhr.responseText);
}
}
xhr.send('参数');
复制代码
readyState
存有 XMLHttpRequest
的状态,0~4
- 请求未初始化
- 服务器连接已经建立
- 请求已接受
- 请求处理中
- 请求已完成,且响应已就绪。
status 就和 http 协议的状态码一样,
使用起来还是比较繁琐的,我反正是没有用过, axios 是二次封装后基于 promise 的网络请求库,浏览器环境和 Node 环境都可以使用,在Node 环境是基于 http
模块,浏览器环境就基于 XMLHttpRequest
了。axios 的使用就简单多了
4. fetch
const url = "http://example.com/";
const options = {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json;charset=UTF-8",
},
body: JSON.stringify({
a: 10,
b: 20,
}),
};
fetch(url, options).then((response) => {
console.log(response.status);
});
复制代码
更加简单就是
fetch(url).then(...).catch(...)
复制代码
fetch 是浏览器自带的,是原生的,拿它和 axios 比较不大合适,应该拿它和 xhr 做比较(偷笑),这样一比较,fetch 可就强多了,支持promise,对 request 和 response 也进行了抽象。然后 fetch 优势就是是浏览器原生支持的,劣势可能就是压不过 axios 这个地头蛇,霸占网络请求多年,一时间比较撼动地位,再加上 fetch 出现的时间比较短,暂时还没有比较成熟的库对它进行封装。
5. 总结
axios 的 cancelToken
有两种方式,用来中断请求。axios.isCancel
方法可以判断是不是请求中断导致的请求异常
ajax 是异步请求的统称,XMLHttpRequest 和 fetch 都是原生请求对象,axios 是基于 XMLHttpRequest 的封装,fetch 和 axios 都支持 Promise.