You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// 添加请求拦截器axios.interceptors.request.use(function(config){// Do something before request is sentreturnconfig;},function(error){// Do something with request errorreturnPromise.reject(error);});// 添加响应拦截器axios.interceptors.response.use(function(response){// Do something with response datareturnresponse;},function(error){// Do something with response errorreturnPromise.reject(error);});
constCancelToken=axios.CancelToken;constsource=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}});source.cancel("Operation canceled by the user.");
axios.CancelToken.source().token 返回的是一个 new CancelToken 的实例,axios.CancelToken.source().cancel , 是 new CancelToken 是传入 new CancelToken 中的方法的一个参数。再看下 CancelToken 这个构造函数:
functionCancelToken(executor){if(typeofexecutor!=="function"){thrownewTypeError("executor must be a function.");}varresolvePromise;this.promise=newPromise(functionpromiseExecutor(resolve){resolvePromise=resolve;});vartoken=this;executor(functioncancel(message){if(token.reason){return;}token.reason=newCancel(message);resolvePromise(token.reason);});}
axios 是目前最常用的 http 请求库,可以用于浏览器和 node.js 。
axios 的主要特性包括:
基于 Promise
支持浏览器和 node.js
可拦截请求与响应
可转换请求与响应数据
请求可以取消
自动转换 JSON 数据
客户端支持防范 XSRF
支持各主流浏览器及 IE8+
axios 使用
发送请求
这是一个官方示例。从上面的代码中可以看到,axios 的用法与 jQuery 的
ajax
方法非常类似,两者都返回一个Promise
对象(在这里也可以使用成功回调函数,但还是更推荐使用Promise
或await
),然后再进行后续操作。添加拦截器函数
从上面的代码,我们可以知道:发送请求之前,我们可以对请求的配置参数(
config
)做处理;在请求得到响应之后,我们可以对返回数据做处理。当请求或响应失败时,我们还能指定对应的错误处理函数。撤销 HTTP 请求
在开发与搜索相关的模块时,我们经常要频繁地发送数据查询请求。一般来说,当我们发送下一个请求时,需要撤销上个请求。因此,能撤销相关请求功能非常有用。
axios
撤销请求的示例代码如下:内部流程图
源码分析
1. 首先,先看看入口是怎么实现的:
axios
入口其实就是通过createInstance
创建出的实例和axios.create()
创建出的实例一样。而源码入口中的重中之中就是createInstance
这个方法。createInstance
流程大致为:Axios
函数创建上下文context
,包含自己的defaults
config
和 管理拦截器的数组Axios.prototype.request
和 上下文创建实例instance
,实例为一个request
发送请求的函数this
指向上下文context
Axios.prototype
的其他方法到instance
实例,this 指向上下文context
context
中的defaults
和拦截器绑定到instance
实例2. 请求别名
在
axios
中axios.get
、axios.delete
、axios.head
等别名请求方法其实都是指向同一个方法axios.request
只是把default config
中的 请求methods
进行了修改而已。 具体代码在Axios
这个构造函数的原型上,让我们来看下源码的实现:因为
post
、put
、patch
有请求体,所以要分开进行处理。请求别名方便用户快速使用各种不同 API 进行请求。3. 拦截器的实现
首先在我们创建实例中,会去创建上下文实例 也就是
new Axios
,会得到interceptors
这个属性,这个属性分别又有request
和response
两个属性 , 它们的值分别是new InterceptorManager
构造函数返回的数组。这个构造函数同样负责拦截器数组的添加和移除。让我们看下源码:上下文环境有了拦截器的数组, 又如何去 做到多个拦截器请求到响应的顺序处理以及实现呢?为了了解这点我们还需要进一步往下看
Axios.protoType.request
方法。5. Axios.protoType.request
Axios.protoType.request
方法是请求开始的入口,分别处理了请求的config
,以及链式处理请求拦截器 、请求、响应拦截器,并返回Proimse
的格式方便我们处理回调。让我们来看下源码部分:我们可以看到
Axios.protoType.request
中使用了精妙的封装方法,形成promise
链 去依次挂载在then
方法顺序处理。6. 取消请求
Axios.prototype.request
调用dispatchRequest
是最终处理axios
发起请求的函数,执行过程流程包括了:adapter
发送请求(浏览器环境使用XMLRequest
对象、Node
使用http
对象)message
,根据配置transformData
转换 响应数据这一过程除了取消请求的处理, 其余的流程都相对十分的简单,所以我们要对取消请求进行详细的分析。我们还是先看调用方式:
从调用方式我们可以看到,我们需要从
config
传入axios.CancelToken.source().token
, 并且可以用axios.CancelToken.source().cancel()
执行取消请求。我们还可以从 看出canel
函数不仅是取消了请求,并且 使得整个请求走入了rejected
。从整个 API 设计我们就可以看出这块的 功能可能有点复杂, 让我们一点点来分析,从CancelToken.source
这个方法看实现过程 :axios.CancelToken.source().token
返回的是一个new CancelToken
的实例,axios.CancelToken.source().cancel
, 是new CancelToken
是传入new CancelToken
中的方法的一个参数。再看下CancelToken
这个构造函数:我们根据构造函数可以知道
axios.CancelToken.source().token
最终拿到的实例下挂载了promise
和reason
两个属性,promise
属性是一个处于pending
状态的promise
实例,reason
是执行cancel
方法后传入的message
。而axios.CancelToken.source().cancel
是一个函数方法,负责判断是否执行,若未执行拿到axios.CancelToken.source().token.promise
中executor
的resolve
参数,作为触发器,触发处于处于pending
状态中的promise
并且 传入的message
挂载在axios.CancelToken.source().token.reason
下。若有 已经挂载在reason
下则返回防止反复触发。而这个pending
状态的promise
在cancel
后又是怎么进入axios
总体promise
的rejected
中呢。我们需要看看adpater
中的处理:取消请求的总体逻辑大体如此,可能理解起来比较困难,需要反复看源码感受内部的流程,让我们大致在屡一下大致流程:
axios.CancelToken.source()
返回一个对象,tokens
属性CancelToken
类的实例,cancel
是tokens
内部promise
的reslove
触发器axios
的config
接受了CancelToken
类的实例cancel
触发处于pending
中的tokens.promise
,取消请求,把axios
的promise
走向rejected
状态手写 axios
看完了源码分析,下面手写一个 axios 就很容易了
常见面试题集锦
参考链接
深入浅出 axios 源码
如何写一个像 axios 那样优秀的请求库
axios —— 极简封装的艺术
学习 axios 源码整体架构,打造属于自己的请求库
手写axios核心原理,再也不怕面试官问我axios原理
The text was updated successfully, but these errors were encountered: