基本使用用法
// 方法1
cancelToken = this.$axios.CancelToken.source()
this.$axios.$get('api', {
params,
{},
cancelToken: cancelToken.token
})
cancelToken.cancel('取消请求');
// 方法2
cancelToken = null
if (cancelToken) {
cancelToken('取消请求')
cancelToken = null
}
this.$axios.$get(url, {
cancelToken: new this.$axios.CancelToken(function (cancelFn) {
cancelToken = cancelFn
})
}).catch(err = > {
// 判断是否是cancelToken类型的取消
if (!this.$axios.isCancel(err)) {
}
})
源码分析
## cancelToken
// 方案2
function CancelToken(executor) {
if (typeof executor !== 'function') {
throw new TypeError('executor must be a function.');
}
var resolvePromise;
this.promise = new Promise(function promiseExecutor(resolve) {
// request.abort();
resolvePromise = resolve;
});
var token = this;
executor(function cancel(message) {
if (token.reason) {
// Cancellation has already been requested
return;
}
token.reason = new Cancel(message);
// 可以在外部控制CancelToken内部的promise对象的resolve了。
resolvePromise(token.reason);
});
}
// 方案1
CancelToken.source = function source() {
var cancel;
var token = new CancelToken(function executor(c) {
cancel = c; // 将cancel函数赋值给cancel
});
return {
token: token, // 返回的是CancelToken 实例, 需要使用内部的promise
cancel: cancel // 返回cancel函数
};
};
CancelToken 初始化的时候需要传递一个方法executor,并且CancelToken内部新建了一个promise,最关键的是,它把promise的resolve方法控制权放在了executor方法里面, 使该promise能够在外部函数执行中进行resolve(也就是在cancel方法中可以使用)
参考
let resolveHandler;
new Promise((resolve) => {
resolveHandle = resolve;
}).then((val) => {
console.log('resolve',val);
});
resolveHandle('ok');
xhr
if (config.cancelToken) {
// Handle cancellation
// cancelToken.promise 中的原始resolve已经被赋值为resolvePromise,只有在cancel调用时候才会resolve
config.cancelToken.promise.then(function onCanceled(cancel) {
if (!request) {
return;
}
// 取消请求
request.abort();
reject(cancel);
// Clean up request
request = null;
});
}
当用户调用cancel方法后,则会resolve(CancelToken实例中promise的resolve) ,然后执行request.abort();
总结
1、核心就是将 CancelToken 中私有变量promise的resolve赋值给另一个变量resolvePromise, 2、然后在实例化CancelToken通过入参CancelToken 将 resolvePrimise的控制交给外部自定义函数 3、使promise能够被外部cancel函数中进行resolve的回调