axios 源码取消请求解析
axios有两种中断请求的方法
1.CancelToken.source 取消所有请求
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.post('/test', {
value: '测试'
}, {
cancelToken: source.token
})
source.cancel('取消请求');
2. 通过 CancelToken
构造函数进行取消 取消单个请求
const CancelToken = axios.CancelToken; let cancel; axios.get("/test/user", { cancelToken: new CancelToken(function executor(c){ cancel = c }) }) cancel("取消请求")
主要代码:
function CancelToken(executor) { if (typeof executor !== 'function') { throw new TypeError('executor must be a function.'); } var resolvePromise; //给实例绑定一个promise,promsie 状态为pending,只有调用resolvePromise 方法时this.promise变为fulfilled状态 this.promise = new Promise(function promiseExecutor(resolve) { resolvePromise = resolve; }); var token = this; // eslint-disable-next-line func-names 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; }); // eslint-disable-next-line func-names this.promise.then = function(onfulfilled) { var _resolve; // eslint-disable-next-line func-names var promise = new Promise(function(resolve) { token.subscribe(resolve); _resolve = resolve; }).then(onfulfilled); promise.cancel = function reject() { token.unsubscribe(_resolve); }; return promise; }; //通过Cancel函数创造一个取消原因信息 executor(function cancel(message) { if (token.reason) { // Cancellation has already been requested return; } //token.reason 就是我们调用cancel方法时传递的信息 token.reason = new Cancel(message); resolvePromise(token.reason); }); }
CancelToken.source = function source() { var cancel; var token = new CancelToken(function executor(c) { cancel = c; }); return { token: token, cancel: cancel }; };
在CancelToken.js 中,发现上面两种中断请求的方法执行的都是同一个方法,
executor(function cancel(message) { if (token.reason) { // Cancellation has already been requested return; } token.reason = new Cancel(message); resolvePromise(token.reason); });
function Cancel(message) { this.message = message; }
token是指创建的CancelToken实例,判断是否有reason这个属性,有则说明已经发起取消请求了直接return,没有就通过Cancel 构造函数创建一个实例, 调用resolvePromise方法。
var resolvePromise; this.promise = new Promise(function promiseExecutor(resolve) { resolvePromise = resolve; });
在创建CancelToken 实例时,添加一个属性promise为Promsie的 实例,且状态为pending,将resolve 方法赋值给resolvePromise.这样resolvePromise 就像取消请求的开关,只有调用了resolvePromsie方法才能执行promise链.
if (config.cancelToken || config.signal) { // Handle cancellation // eslint-disable-next-line func-names onCanceled = function(cancel) { if (!request) { return; } reject(!cancel || (cancel && cancel.type) ? new Cancel('canceled') : cancel); request.abort(); request = null; };
config.cancelToken && config.cancelToken.subscribe(onCanceled);
CancelToken.prototype.subscribe = function subscribe(listener) { if (this.reason) { listener(this.reason); return; } if (this._listeners) { this._listeners.push(listener); } else { this._listeners = [listener]; } };
xhr.js根据cancelToken调用subscribe方法,当this.reason存在时调用 XMLhttpRquest 取消方法。this.reason就是前面Cancel生成的实例。
以上就是axios取消请求的基本流程。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)