axios.CancelToken

mac2026-04-06  2

在公司项目中看到之前代码使用了axios.CancelToken,但自己对这个并不了解,所以去查了查,下面是我的一些总结,如有错误,一经提出立即改正。

axios.CancelToken官方文档:

使用方法如下:需要注意的是在get请求中CancelToken作为第二个参数传入,在post请求中CancelToken作为第三个参数传入

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.');

知道了使用方法后,最重要的我们是要搞清楚Cancel.Token的取消请求是怎么实现的,下面看一段源码

'use strict'; var Cancel = require('./Cancel'); function CancelToken(executor) { if (typeof executor !== 'function') { throw new TypeError('executor must be a function.'); } var resolvePromise; this.promise = new Promise(function promiseExecutor(resolve) { resolvePromise = resolve; }); var token = this; executor(function cancel(message) { if (token.reason) { // Cancellation has already been requested return; } token.reason = new Cancel(message); resolvePromise(token.reason); }); } CancelToken.prototype.throwIfRequested = function throwIfRequested() { if (this.reason) { throw this.reason; } }; CancelToken.source = function source() { var cancel; var token = new CancelToken(function executor(c) { cancel = c; }); return { token: token, cancel: cancel }; }; module.exports = CancelToken;

从上面的代码可以看出在CancelToken这个类初始化的时候需要传递一个executor参数,在这个类的内部还创建了一个promise,然后定义了一个变量,把promise的resolve方法控制权放在了exexutor方法的执行体中。 这样做的目的是为了可以在外面控制promise的resolve。在promise的外部定义了一个resolvePromise 变量,在promise的内容将resolve赋值给了resolvePromise 这个变量,所以可以通过直接调用resolvePromise 来执行promise的resolve。 下面看下source这个方法同样的在这个方法中也定义了一个变量cancel,并且在这个方法内容new了一个CancelToken,并且传入一个参数c,并且将c赋值给了cancel,那么c又是代表的什么呢? 从上面代码可以看出,c就代表的是CancelToken类初始化的时候传入的executor,代码如下:

function cancel(message) { if (token.reason) { // Cancellation has already been requested return; } token.reason = new Cancel(message); resolvePromise(token.reason); }

也就是说将上面的这个方法赋值给了cancel,可以通过这个方法控制CancelToken内部的promise对象。 在sourse方法中,还有一个token,这个token是CancelToken这个类的一个实例,可以访问到CancelToken内部的promise。 这样封装的目的是为了能够分离promise和resolve方法,让用户可以自主调用resolve,一旦resolve就会触发promise的then,那promise的then又做了什么呢?

if (config.cancelToken) { // Handle cancellation config.cancelToken.promise.then(function onCanceled(cancel) { if (!request) { return; } request.abort(); reject(cancel); // Clean up request request = null; }); }

可以看到当调用cancel方法后,会理解执行abort方法取消请求,同时调用reject让外层的promise的reject执行。

变量c正是我们前面说到的在CancelToken初始化时,传入executor方法的,也即:

最新回复(0)