需求
- 拦截请求
- 转换请求数据
- 转换响应数据
- 请求头的改写
- 添加拦截锁定期
- 支持拦截器内部异步处理
promise 的基础知识
- promise的then方法,then 的第一个执行器里面返回值的可能请求
- 没有返回值
- 返回值是为 ReturnPromise 对象,在下一个 then 的时候,第一个执行器的参数是 上一个 ReturnPromise 的 resolve 或者 reject 的值。
- 返回值不是promise,是数据类型,下一个then函数的第一个执行器的参数能,拿到的就是这数据
- promise 的value 是内部数据类型,只能在then中拿到,外部是拿不到的
- 我们要在then实现异步任务,现在做好的办法就是使用返回一个promise 并且决策下一个then需要的值!
拦截流程
- 发起一个http请求
- 调用
__defaultRequest方法 __defaultRequest遍历拦截器函数,缓存拦截器函数,具体的流程promise连接处理请求- Promise.resolve(?config)
- 遍历拦截器
- 注入拦截器
- 发起http请求
- 注入响应拦截器
- 返回promise
这里面一个需求就是添加🔐,我们能够中断后面的请求,
改进
- 我们将请求拦截器和响应拦截器,分开添加,做到和axios具有相同的开发体验
- 我们无感授权的时候,我们要将过期的登录的请求,锁在一个队列中,等到无感授权之后,我们要将这些请求重新执行,这里有个类似于与 axios 的包 flyio
问题的解决方案
拦截器的开始是:
// 初始化拦截器
let requestInterceptors = []
let responseInterceptors = []
// 初始化拦截器的promise
let promise = Promise.resolve(?config)
// 缓存拦截器
this.interceptors.forEach(n => {
// n 是注册拦截器,保存在 handlers 里面
if (n.request || n.requestError) {
requestInterceptors.push(n.request, n.requestError)
}
// reponse 函数参数:response 目前还不知道是啥
if (n.response || n.responseError) {
responseInterceptors.unshift(n.response, n.responseError)
}
})
// 添加请求拦截器
promise = chainInterceptors(promise, requestInterceptors)
// 发起 http 请求
promise = promise.then(serverRequest)
// 注入响应拦截器
promise = chainInterceptors(promise, responseInterceptors)
// 返回这个 promise
return promise
获取一个 promise 的值,我们可以知道,其实拦截器里面的东西就是一个链式的 promise, 处理了之后教给下一个 promise,然后把这个 promise 返回出来。
理解注入拦截器
首先注入的拦截也是要返回的 promise, 才能被链式调用。注入拦截函数的参数promise, 和 interceptors(请求拦截器),
const chainInterceptors = (promise, interceptors) => {
for (let i = 0, ii = interceptors.length; i < ii;) {
let thenFn = interceptors[i++]
let rejectFn = interceptors[i++]
// then方法调用之后,形成一个新的Promise
// thenFn 参数是 request 此时是
promise = promise.then(thenFn, rejectFn)
}
return promise
}
const transformData = (data, header, status, fns) => {
fns.forEach(fn => {
data = fn(data, header, status)
})
return data
}
const serverRequest = config => {
const __config = Object.assign({}, config, {
data: transformData(?config.data, ?config.header, undefined, defaults.transformRequest),
})
return this.__http(__config).then(transformResponse,transformResponse)
}
请求的关于拦截器的部分
- 定义拦截器缓存器
- Promise 决策请求配置文件配置文件
- 遍历拦截器,将拦截器函数,放到拦截器缓存器
- 注入请求拦截器,注入请求拦截,就是使用 promise的then方法执行request函数,request 返回的也是 promise 的情况,这里还是一份请求的配置,请求的配置被决策到新的promise里面,在promise 里面把请求发送出去。请求的也是一个函数吗,在promise 的then的链式调用中
- 发起请求,底层使用 wx.request(obj) + promise 来实现功能
- 注入响应拦截器
- 返回 promise