携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
axios发送请求后,我们还可以对其取消请求操作,我们来实现一下取消请求,我们先创建一个取消构造函数
// 取消构造函数
function CancelToken(executor){
//声明一个变量,用于取消请求的执行
let resolvePromise;
// 为实例对象添加属性,此时如果进行实例化对象,那么实例化对上就有一个promise属性。并且值为promise对象,而且还是一个pending状态的promise,将resolve赋值给resolvePromise,这样的话只需要调用resolvePromise就可以改变当前promise属性的状态
this.promise=new Promise((resolve)=>{
resolvePromise=resolve
})
// 调用exector函数,他接受一个回调函数,他做的事情就是执行resolvePromise函数,这样就把当前实例对象上的promise对象状态变为成功
executor(function(){
resolvePromise()
})
}
在把取消请求操作添加到我们发送请求的适配器中,通过请求配置判断是否取消请求
function xhrAdapter(config) {
return new Promise((resolve, reject) => {
const XHR = new XMLHttpRequest()
XHR.open(config.method, config.url);
XHR.send()
XHR.onreadystatechange = function() {
// 判断请求状态是否成功
// 0:开始发送请求
// 1:正在发送请求
// 2:已经接收到全部响应内容
// 3:正在解析响应内容
// 4:请求完成
if (XHR.readyState == 4) {
if (XHR.status >= 200 && XHR.status < 300) {
resolve({
// 配置对象
config: XHR.config,
// 响应体
data: XHR.response,
// 响应头
headers: XHR.getAllResponseHeaders(),
// XHR请求对象
request: XHR,
// 响应的状态码
status: XHR.status,
// 响应状态字符串
statusText: XHR.statusText,
});
} else {
// 失败就抛出错误
reject(new Error('请求失败'))
}
}
}
// 我们将取消请求放在这里,我们不能直接放在这里,因为会导致请求一发送就直接被取消的情况,所以我们这里就加一个判断,如果请求配置中包含了cancelToken参数,就执行把请求取消掉,顺带抛出请求执行失败
if(config.cancelToken){
config.cancelToken.promise.then(res=>{
xhr.abort()
// 将请求结果设置为失败
reject(new Error('请求已经取消'))
})
}
})
}
我们创建俩个按钮,一个是发送请求,一个是取消请求
<button>发送请求</button>
<button>取消请求</button>
通过js获取到按钮元素进行绑定对应执行的事件
//声明一个全局变量,用于存储取消请求函数,便于执行
var cancal;
// 发送请求
btns[0].click = function() {
//当我们去new CancelToken的时候,里面的代码就会执行,里面也会有一个promise属性,我们将executor回调函数传递进去,接受一个参数,也是一个回调函数,通过executor执行将promise的值赋值给cancal,只要我们这里一执行这个cancal就可以去取消请求
let cancelToken = new CancelToken(function(callback) {
cancal = callback;
})
axios({
method: 'GET',
url: 'http://xxxx.com/login',
cancelToken: cancelToken
}).then(res => {
console.log(res)
cancal = null
})
}
// 取消请求
btns[1].click = function() {
//发送请求时,把取消的执行函数存储到了cancal变量中,所以我们在这里直接执行就可以了
cancal()
}
坚持努力,无惧未来!