拦截器管理类的实现
接口定义
// ./src/type/index.ts
export interface AxiosInterceptorManager<T> {
use(resolved: ResolvedFn<T>, rejected?: RejectedFn) : number
eject(id: number): void
}
export interface ResolvedFn<T> {
(val: T) : T | Promise<T>
}
export interface RejectedFn {
(error: any): any
}
具体实现
// ./src/core/InterceptorManger.ts
import { ResolvedFn, RejectedFn } from "../types"
interface Interceptor<T> {
resolved: ResolvedFn<T>
rejected?: RejectedFn
}
export default class InterceptorManager<T> {
private interceptors: Array<Interceptor<T> | null>
constructor() {
this.interceptors = []
}
use(resolved: ResolvedFn<T>, rejected?: RejectedFn): number {
this.interceptors.push({
resolved,
rejected
})
return this.interceptors.length - 1
}
forEach(fn: (interceptor: Interceptor<T>) => void): void {
this.interceptors.forEach(interceptor => {
if (interceptor !== null) {
fn(interceptor)
}
})
}
eject(id: number): void {
if (this.interceptors[id]) {
this.interceptors[id] = null
}
}
}
链式调用实现
// ./src/core/Axios.ts
import { AxiosRequestConfig, AxiosPromise, Method, AxiosResponse, ResolvedFn, RejectedFn } from '../types'
import dispatchRequest from './dispatchRequest'
import InterceptorManager from './InterceptorManager'
interface Interceptors {
request: InterceptorManager<AxiosRequestConfig>
response: InterceptorManager<AxiosResponse>
}
interface PromiseChain<T> {
resolved: ResolvedFn<T> | ((config: AxiosRequestConfig) => AxiosPromise)
rejected?: RejectedFn
}
export default class Axios {
interceptors: Interceptors
constructor() {
this.interceptors = {
request: new InterceptorManager<AxiosRequestConfig>(),
response: new InterceptorManager<AxiosResponse>()
}
}
request(url: any, config?: any): AxiosPromise {
if (typeof url === 'string') {
if (!config) {
config = {}
}
config.url = url
} else {
config = url
}
const chain: PromiseChain<any>[] = [{
resolved: dispatchRequest,
rejected: undefined
}]
this.interceptors.request.forEach(interceptor => {
chain.unshift(interceptor)
})
this.interceptors.response.forEach(interceptor => {
chain.push(interceptor)
})
let promise = Promise.resolve(config)
while (chain.length) {
const { resolved, rejected } = chain.shift()!
promise = promise.then(resolved, rejected)
}
return promise
}
//...
}
// ./src/type/index.ts
//...
export interface Axios {
intercptors: {
request: AxiosInterceptorManager<AxiosRequestConfig>
response: AxiosInterceptorManager<AxiosResponse>
}
//...
}
测试
// ./examples/interceptors/app.ts
import axios from '../../src/index'
axios.interceptors.request.use(config => {
config.headers.test += '1'
return config
})
axios.interceptors.request.use(config => {
config.headers.test += '2'
return config
})
axios.interceptors.request.use(config => {
config.headers.test += '3'
return config
})
axios.interceptors.response.use(res => {
res.data += '1'
return res
})
let interceptor = axios.interceptors.response.use(res => {
res.data += '2'
return res
})
axios.interceptors.response.use(res => {
res.data += '3'
return res
})
axios.interceptors.response.eject(interceptor)
axios({
url: '/interceptor/get',
method: 'get',
headers: {
test: ''
}
}).then(res => {
console.log(res.data)
})