【源码】Axios取消功能源码阅读

前言

axios库提供了取消请求的功能,虽然个人平时很少用到。

正文

下面是官网的两个例子:

const CancelToken = axios.CancelToken;
let cancel;
 
axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    cancel = c;
  })
});

cancel();

第一个例子中,在axios请求时传递cancelToken参数,该参数为CancelToken的实例,创建该时可获取到cancel函数的引用。调用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 {
    // handle error
  }
});
 
axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})
 
// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');

第二个例子中,使用CancelToken.source()返回一个source对象,包含了tokencancel,将token传递给请求参数,然后调用cancel即可取消对应的请求。

下面是axios的大体目录:

image.png

先从第一个例子开始,找到挂在axios下的CancelToken文件。看一下new CancelToken时做了什么:

image.png

创建了一个promise,保持为pending状态。然后将cancel传递出去,函数中调用了resolve。而生成的实例有两个属性:this.promisethis.reason(这个reason是调用cancel时才被赋值的,作为是否已经取消过的标志)。而这个实例就被传递到cancelToken请求参数中了。

下面看看cancelToken请求参数在发送请求时起到的作用。在lib/core/Axios.js中可以看到request函数,调用的是dispatchRequest发送请求。

image.png

随带一提,request中使用了promise的链式调用,chain数组中包含了请求拦截器、响应拦截器,而dispatchRequest则是夹在两者的中间。这就是Axios拦截器的原理。

那么我们就进入dispatchRequest.js中看一下它做了什么:

image.png

可以看出adapter是一个promise,这个adapter默认是什么呢?在default.js中可以看到,adapter在浏览器端是XHR,在Node使用的是http(所以axios是兼容服务端的)。

image.png

adapter顾名思义是适配器的意思,这里也是使用了适配器设计模式,允许开发者自己传入请求对象。而不是将请求固定死为xhr或者Node.js的http库。

那么我们这里看一下xhr.js,在这个文件中我们终于要发送请求了:

image.png

前面一堆根据config对xhr进行配置不看,直接看到最后的cancelToken,我们可以看到,如果传递了cancelToken参数,则在cancelTokenpromise状态变为resolved时执行:request.abort();中断请求。

那么promise什么时候resolved呢?由前面所述,resolve函数被暴露出来赋值给cancel引用。那么,当我们调用cancel时,promise状态变为resolved,请求被取消。就是这样。

再来看看第二个例子,第二个例子就是进行了一下封装。由第一个例子可知,我们使用时需要的就是cancelToken和对应的cancel方法。axios提供一个静态方法,将两个东西一并返回给我们:

image.png

这样子,我们就不用像第一个例子那样还要传递一个回调函数来拿cancel函数了。

你可能感兴趣的:(【源码】Axios取消功能源码阅读)