目录
- 介绍
- 初始化:axios 、Axios、intance
- 整体流程:request => deispatchRequest => Adapter
- 数据转换:despatchRequest
- 适配器:Adapter
- 拦截器:request => deispatchRequest => response
- 取消请求:cancelToken => adapter => cancel
- 回顾
介绍
特点:
- 支持浏览器与Node.js
- API promise
- 请求/响应拦截器
- 请求/响应格式化方法
- 取消请求
用法:
// 直接发送请求
axios(config)
axios(url[, config])
axios.request(config)
// 别名方法
axios.get(url[, config])
axios.delete(url[, config])
axios.post(url[, data, config])
axios.put(url[, data, config])
axios.defaults.xxx: 请求的默认全局配置
axios.interceptors.request.use(): 添加请求拦截器
axios.interceptors.response.use(): 添加响应拦截器
axios.create([config]): 创建一个新的 axios
// 只有默认axios有的方法,新创建的没有
axios.Cancel(): 用于创建取消请求的错误对象
axios.CancelToken(): 用于创建取消请求的 token 对象
axios.isCancel(): 是否是一个取消请求的错误
axios.all(promises): 用于批量执行多个异步请求
axios.spread():
复制代码
目录结构
├── adapters
│ ├── README.md
│ ├── http.js // Node环境请求
│ └── xhr.js // 浏览器环境请求
├── axios.js // 入口文件 初始化
├── cancel // 请求取消模块
│ ├── Cancel.js
│ ├── CancelToken.js
│ └── isCancel.js
├── core // 核心模块
│ ├── Axios.js // 初始化
│ ├── InterceptorManager.js // 拦截器管理
│ ├── buildFullPath.js
│ ├── createError.js
│ ├── dispatchRequest.js // 请求调用
│ ├── enhanceError.js
│ ├── mergeConfig.js
│ ├── settle.js
│ └── transformData.js // 数据转换
├── defaults.js // 默认配置
├── env
│ ├── README.md
│ └── data.js
├── helpers
│ ├── README.md
│ ├── bind.js // bind
│ ├── buildURL.js
│ ├── combineURLs.js
│ ├── cookies.js
│ ├── deprecatedMethod.js
│ ├── isAbsoluteURL.js
│ ├── isAxiosError.js
│ ├── isURLSameOrigin.js
│ ├── normalizeHeaderName.js
│ ├── parseHeaders.js
│ ├── spread.js
│ └── validator.js
└── utils.js // 类型判断、对象方法(forEach、merge、extend)
复制代码
初始化
带着这个问题开始 axios与Axios的关系? 入口文件lib/axios.js,通过 工厂函数 createInstance 初始化,得到axios,并给axios挂载Cancel、CancelToken等方法。
初始化的流程开始从工厂函数 createInstance开始:
- Axios构造函数生成对象带有defaults属性和拦截器属性的对象
- bind(request, content) 返回一个闭包的request方法。
- 拷贝Axios.prototype(get/post/request)
- 拷贝context上的 defaults 和 拦截器属性。
逐行分析 + debugger:
- Axios构造函数生成对象带有defaults属性和拦截器属性的对象
- bind(request, content) 返回一个闭包的request方法。
var context = new Axios(defaultConfig);
var instance = bind(Axios.prototype.request, context);
复制代码
- 拷贝Axios.prototype(get/post/request)
utils.extend(instance, Axios.prototype, context);
复制代码
- 拷贝context上的 defaults 和 拦截器属性。
Axios构造函数: delete、get等方法都是request的别名,只不过是合并了一下不同的配置config配置。
axios 与 Axios 的关系
- 语法上:axios 不是Axios的对象实例
- 功能上:axios 具备 Axios实例上的所有功能(方法:Axios.porotype、属性:defaults/interceptors)
- axios 是 Axios.porotype.request 函数 bind返回的 warp 函数,可直接使用。
axios.created 创建的对象 与 axios 的区别
相同:直接发送请求、具有request、get/post方法,具有defaults/interceptors属性。 不同:新的instance 不具有 Cancel、CancelToken方法。
15
整体流程
责任链模式
行为模式负责对象间的高效沟通和职责委派。
责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
模块流程: Axios.porotype.request(config) ==> despatchRequest(config) ==> adapter(config)
重要模块与职责:
- request: 请求拦截 => despatchRequest => 响应拦截,通过promise串联
- despatchRequest: 请求数据转换 => adapter => 响应数据转换
- adpter:根据环境确定请求函数 返回promise
整体流程:
转换数据 despatchRequest
默认转换
适配器
结构型模式介绍如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效。
适配器模式是一种结构型设计模式, 它能使接口不兼容的对象能够相互合作。
拦截器
拦截器管理
取消拦截器? 拦截器执行顺序?
lib/core/InterceptorManager.js
- user:添加
- eject:删除
- forEach:获取所有
添加/取消拦截器
lib/core/Axios.js Axios.prototype.request
异步执行
同步执行
执行顺序
写一个demo
const config = {a:'111'}
const promise = Promise.resolve(config);
const arr = [promise]
let resault = promise
arr.push((config) => {
config['user1'] = 111
console.log(config, '111')
return config
})
arr.push((config) => {
config['user2'] = 2222
console.log(config, '222')
return config
})
arr.push((config) => {
config['user3'] = 3333
console.log(config, '333')
return config
})
while (arr.length) {
resault = promise.then(arr.shift())
}
复制代码
取消请求
取消的使用
lib/cancel/CancelToken.js 主函数与subscribe
订阅函数
第一步 生成 cancelToken = new axios.CancelToken(c => cancel = c)
第二步 xhr内 cancelToken.subscribe 存储取消事件
第三步 执行通过subscribe存储的取消事件
观察者模式
观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。
观察者模式与发布订阅的关系 讨论? 观察者模式包含发布订阅。 发布订阅是观察者的升级变种。 观察者模式与发布订阅的区别是否有事件调度中心。
回顾
- axios 、Axios 的区别、初始化流程
- config责任链,关键模块 request、despatchRequest、adpter 的职责, 请求整体流程。
- despatchRequest的default转换 自动转json
- 适配器实现
- request 拦截器实现,取消拦截器、执行顺序。
- 取消请求的实现
感悟:
- 模块职责清晰
- 适配器易扩展
- 拦截器、格式转换灵活
- 设计模式的分类:创建型、结构型、行为型
- 技巧与方法 && 持续学习