一、使用方法
- 取消单个请求
通过传递一个 executor 函数到
CancelToken
的构造函数来创建 cancel token:
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函数接收一个 cancel 函数作为参数
cancel = c;
})
});
cancel();//取消
- 同时取消多个请求
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.get('/user/123456', {
cancelToken: source.token
})
axios.post('/user/12345', {
name: 'new name'
}, {
cancelToken: source.token
})
// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');
二、基本原理
canceltoken 是通过发布订阅模式实现的,将axios.CancelToken构造器的实例通过cancelToken传入,就会调用实例上的subscribe方法订阅取消消息,再根据需求执行cancel方法触发订阅器取消请求。
-
核心代码
function 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;
// _listeners 是一个存放订阅器的数组
//cancel调用后执行 _listeners里面的订阅器
this.promise.then(function(cancel) {
if (!token._listeners) return;
var i;
var l = token._listeners.length;
for (i = 0; i < l; i++) {
token._listeners[i](cancel);
}
token._listeners = null;
});
//cancel方法里面调用promise的resolve
executor(function cancel(message) {
if (token.reason) {
// Cancellation has already been requested
return;
}
token.reason = new CanceledError(message);
resolvePromise(token.reason);
});
}
-
原型方法
- throwIfRequested:如果请求已经取消或者请求完毕就会触发调用
- subscribe:将订阅器添加到_listeners里面
.../lib/adapters/xhr.js
function xhrAdapter(config) {
return new Promise(function dispatchXhrRequest(resolve, reject) {
...
if (config.cancelToken || config.signal) {
onCanceled = function(cancel) {
if (!request) {
return;
}
reject(!cancel || (cancel && cancel.type) ? new CanceledError() : cancel);
request.abort();
request = null;
};
config.cancelToken && config.cancelToken.subscribe(onCanceled);
}
}
}
3.unsubscribe:取消订阅(接口请求完成都会调用)
-
source方法
返回一个具有token和cancel属性的对象,都是通过CancelToken这个构造函数来的,
CancelToken.source = function source() {
var cancel;
var token = new CancelToken(function executor(c) {
cancel = c;
});
return {
token: token,
cancel: cancel
};
};