axios取消请求原理分析

110 阅读1分钟

如何使用axios取消请求

这里使用的是0.22.0之前的版本,要注意0.22.0之后已采用AbortController代替CancelToken

let myCancel = null;
const fn = (c) => {
    // 将 c 的值赋值给 全局变量cancel。
    myCancel = c;
}
//创建 cancelToken 的值
let cancelToken = new axios.CancelToken(fn);

axios({
    method: 'GET',
    url: 'http://localhost:3000/posts',
    // 添加配置对象的属性
    cancelToken: cancelToken
}).then(response => {
    console.log(response);
    cancel = null;//防止内存泄漏
})

//取消请求
myCancel();

这里有点类似于setTimeoutclearTimeout。在CancelToken函数的参数里再里传入一个函数fn,fn函数的参数c类似于timer,可以通过调用c()来模拟clearTimeout(timer)的效果。

 const timer = setTimeout(() => {
        console.log('3s...')
}, 3000);

clearTimeout(timer);

源码目录结构

image.png

源码分析

从lib/axios.js进入,找到axios.CancelToken

image.png

进入lib/cancel/CancelToken.js,找到CancelToken函数

image.png

17行的this.promise上存放的是一个Promise,而这个Promiseresolve函数被一个resolvePromise变量所保存。

这里的executor实际上就是你传入的fn函数,所以22行会执行你传入的fn函数,源码里的cancel函数也就被你保存到了全局变量myCancel上。

当你调用myCancel时,也就是调用了cancel函数cancel函数会调用resolvePromise函数resolvePromise函数又会将17行的this.promise的Promise由pending状态变为fulfilled状态。这有什么意义呢?

进入lib/adapters/http.js,找到httpAdapter函数

image.png

208行的config.cancelToken.promise也就是上文的this.promise,所以当Promise状态改变时,也就是会执行208行的onCanceled函数,从而执行213行的req.abort()去取消请求。