肆:Cancel与CancelToken
前边碰到取消请求相关的部分内容都是直接略过的,现在主线任务已经完成了,好好看一下支线任务Cancel与CancelToken吧。
取消请求的相关源码存放在lib/cancel目录下,我们先分析一下该目录下的几个文件,然后看一下在axios中是怎么使用他们的。
Cancel类
Cancel类的内容太简单了,构造函数接收一个message,原型对象上有一个方法和一个属性。直接贴代码吧。
1 | function Cancel(message) { |
isCancel方法
isCancel方法就更简单了,在Cancel类中我们知道Cancel实例的原型对象上有一个属性__CANCEL__的值为true,就判断一下就可以了。
1 | function isCancel(value) { |
CancelToken类
CancelToken类才是重点,我们前边在dispatchRequest等地方忽略的内容就用到了CancelToken实例的方法。
CancelToken是一个可以用于取消请求的对象
CancelToken类接收一个函数,在内部会调用这个函数并传入一个新的函数cancel作为参数。
注意CancelToken实例上会有一个属性promise,这个promise在cancel函数内才会resolve。
1 | function CancelToken(executor) { |
原型对象上有一个方法throwIfRequested。如果CancelToken实例上有reason就抛出错误抛出reason也就是Cancel实例。
1 | CancelToken.prototype.throwIfRequested = function throwIfRequested() { |
CancelToken类还有一个source方法,方法返回一个对象包含CancelToken实例和用于取消请求的方法。
1 | CancelToken.source = function source() { |
开发中使用CancelToken取消请求
看了CancelToken的源码肯定是有些懵的,为什么要这么做呢?
我们看一下在真正的开发过程中可以使用的一种取消请求方式:
调用source拿到取消方法,调用这个方法取消请求
1 | const CancelToken = axios.CancelToken; |
再看一下另一种方式:
这个就有点像是自己实现了source方法了,最后还是调用了这个取消请求的方法
1 | const CancelToken = axios.CancelToken; |
现在应该对于CancelToken有一些理解了,虽然我没get到这样设计的好处。
至于为什么调用取消请求的方法就能取消请求了我们往下看哦。
在xhr中的应用
前边在dispatchRequest和xhr中都略过了取消请求的部分。
dispatchRequest中就是调用了CancelToken的throwIfRquested这个方法,就不单独说了。
看一下在xhr中的使用,大家要记得CancelToken中的promise我们还没用到呢。在xhr中有如下代码,位于XMLHttpRequest.send()之前。
1 | if (config.cancelToken) { |
大家应该记得在CancelToken中执行了executor并传入了一个函数cancel。如果执行cancel这个函数就会将promise给resolve对吧,所以在我们执行了取消请求的方法之后,promsie会resovle进入.then内部会通过abort方法取消正在进行的异步请求然后在xhr中的promise中调用reject抛出错误。这样请求就被取消了。
即便到现在我也不理解为什么只有axios可以使用CancelToken,但是axios.create创建的实例却不能。
就像在axios1.x版本中,通过axios.create创建的实例可以继续调用create创建实例了,但依然不能取消请求。
关于axios新版本,看时间安排尽量出一期新版本的改动内容吧。
肆:Cancel与CancelToken
https://zhaolei-hu.github.io/2022/10/26/肆-Cancel与CancelToken/