axios源码分析(3)之请求取消
之前分析了2篇文章:
接下来,我们今天分析axios的取消这块的实现,老规矩,先来段使用api助兴一下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15var CancelToken = axios.CancelToken;
var source = CancelToken.source();
axios.get('/get?name=xmz', {
cancelToken : source.token
}).then((response)=>{
console.log('response', response)
}).catch((error)=>{
if(axios.isCancel(error)){
console.log('取消请求传递的消息', error.message)
}else{
console.log('error', error)
}
})
// 取消请求
source.cancel('取消请求传递这条消息');
根据这个例子,我又找到了axios/lib/axios.js
1
axios.CancelToken = require('./cancel/CancelToken');
找到axios/lib/cancel/CancelToken.js
1
2
3
4
5
6
7
8
9
10CancelToken.source = function source() {
var cancel;
var token = new CancelToken(function executor(c) {
cancel = c;
});
return {
token: token,
cancel: cancel
};
};
这里看出source执行完之后,返回一个还有token跟cancel的对象,token,也是一个对象,这个cancel到底是什么还不得而知,继续看下CancelToken这个类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21function CancelToken(executor) {
if (typeof executor !== 'function') {
throw new TypeError('executor must be a function.');
}
var resolvePromise;
this.promise = new Promise(function promiseExecutor(resolve) {
resolvePromise = resolve;
});
var token = this;
executor(function cancel(message) {
if (token.reason) {
// Cancellation has already been requested
return;
}
token.reason = new Cancel(message);
resolvePromise(token.reason);
});
}
从这里我们可以看出CancelToken中含有一个promise,并且上面source中的c就是这里的cancel函数,所以我们使用的source.cancel('取消请求传递这条消息');
就是这里的cancel函数,所以这里source.cancel('取消请求传递这条消息');
最重要的就是执行resolvePromise()
,这个resolvePromise
是什么呢?其实就是this.promise中执行then中的回调函数,那这个then中的回调函数在哪里,在axios/lib/adapters/xhr.js
1
2
3
4
5
6
7
8
9
10if(config.cancelToken){
// 具体是如何取消的,是在这个判断内定义的;
config.cancelToken.promise.then(function(cancel){
request.abort();
reject(cancel);
request = null;
})
}
// 发送请求
request.send(requestData);
看见了这段,就连接起来了,resolvePromise()
就是要执行这里的then的回调函数,就达到了取消request的效果
好了,总结一下:执行cancel是让token的promise变成成功,在真正发送请求之前,验证token.promise的状态是否已经变了,如果变了,就取消请求,就是这样一个简单的思想来进行取消请求的