axios 源码分析-取消请求
2020-03-01 16:24
961 查看
使用取消请求
有的时候我们会进行一些耗时比较长的请求,如果中途我们不想再继续了,如何能够取消请求呢,先看看axios官方文档关于取消请求的用法
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.');
通过
axios.CancelToken.source()得到一个对象,这个对象有两个属性,一个是
token,一个是
cancel方法,通过config把
token传给我们想要取消的请求,然后调用
cancel方法,就能够取消我们的请求,并且在
catch里面得到我们调用
cancel时传入的消息。
CancelToken
我们在axios源码找到
CancelToken类,位置在
/lib/cancel/CancelToken.js
CancelToken.source = function source() { var cancel; var token = new CancelToken(function executor(c) { cancel = c; }); return { token: token, cancel: cancel }; };
可以看出我们调用的
axios.CancelToken.source()方法返回的对象里面是
token和
cancel,
token就是
CancelToken的实例。
其中
cancel就是从实例里面拿到的
c方法。我们再来看一下
CancelToken的内容。
function CancelToken(executor) { 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传入一个函数,通过这个函数把
function cancel(message)返回给了
CancelToken.source().cancel。
CancelToken.source().token有
promise和
reason两个属性,
promise一直处于 pending状态,
reason属性是一个
Cancel类的实例,Cancel类的构造函数如下:
// /lib/cancel/Cancel.js function Cancel(message) { this.message = message; } Cancel.prototype.toString = function toString() { return 'Cancel' + (this.message ? ': ' + this.message : ''); }; Cancel.prototype.__CANCEL__ = true;
可以看出
reason属性里只有一个
message。也就是我们取消请求时传入的消息。那是如何把这个消息抛出的呢,在
axios的拦截器里面的调用
CancelToken.prototype.throwIfRequested来抛出消息。
// /lib/core/dispatchRequest.js function throwIfCancellationRequested(config) { if (config.cancelToken) { config.cancelToken.throwIfRequested(); } } // 拦截器 module.exports = function dispatchRequest(config) { // 判断是否已经取消请求 throwIfCancellationRequested(config); /* ... */ }; // /lib/cancel/CancelToken CancelToken.prototype.throwIfRequested = function throwIfRequested() { if (this.reason) { throw this.reason; } }
检测
config.cancelToken是否有
reason属性,如果有,将
reason抛出,
axios进入
rejected状态。
我们知道
axios其实就是帮我们封装了js的
XMLHttpRequest对象,我们可以看一下
XMLHttpRequest的文档,在文档中我们知道取消请求的方法是
abort()的,所以前面处理那么多只是为了调用这个请求的
abort()方法。
// lib/adapters/xhr.js if (config.cancelToken) { // Handle cancellation config.cancelToken.promise.then(function onCanceled(cancel) { if (!request) { return; } // 取消请求 request.abort(); // promise进入rejected reject(cancel); // Clean up request request = null; }); }
这段代码把
onCanceled传给了
cancelToken.promise属性,所以当我们调用
cancelToken.promise的
resolve函数时,就会调用这个方法,通过这个方法调用
request.abort()取消请求和改变请求的状态,使catch中抛出错误。
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- 从 axios 源码中了解到的 Promise 链与请求的取消
- struts2请求过程源码分析
- springMVC源码分析--访问请求执行ServletInvocableHandlerMethod和InvocableHandlerMethod
- 详解Axios 如何取消已发送的请求
- Volley网络请求封装之LruCache源码分析
- axios取消重复请求
- Struts2源码分析--请求处理
- springMVC源码分析--RequestToViewNameTranslator请求到视图名称的转换
- Tomcat7.0源码分析——请求原理分析(下)
- [置顶] SpringMVC一次请求过程源码分析
- Struts2请求处理流程及源码分析
- OkHttp 3.7源码分析(二)——拦截器&一个实际网络请求的实现
- nginx源码分析--多阶段请求处理
- Tomcat源码分析(二)------ 一次完整请求的里里外外
- Struts2请求处理流程及源码分析
- 知识小罐头06(tomcat8请求源码分析 中)
- Tornado源码分析之HTTP服务请求解析
- Zookeper源码分析之请求调用链(一)RequestProcessor类
- 日常开发——Android网络请求openConnection()源码分析
- shiro源码分析篇2:请求过滤,登录判断