需求
请求之前拦截请求数据,响应之后拦截响应数据。
- 可支持多个拦截器。
- 可移除
- 请求拦截器先添加,后执行,响应拦截器先添加先执行
// 添加一个请求拦截器axios.interceptors.request.use(function (config) {// 在发送请求之前可以做一些事情return config;}, function (error) {// 处理请求错误return Promise.reject(error);});// 添加一个响应拦截器axios.interceptors.response.use(function (response) {// 处理响应数据return response;}, function (error) {// 处理响应错误return Promise.reject(error);});
整体设计

形成一个Promise链式调用。定义拦截器管理类
```typescript import { ResolvedFn, RejectedFn } from “../types”
interface Interceptor
export class InterceptorManager
constructor() { this.interceptors = [] }
use(resolved: ResolvedFn
eject(id: number) { if (this.interceptors[id]) { this.interceptors[id] = null } }
forEach(fn: (item: Interceptor
<a name="SROEO"></a>## 实现整体设计,链式调用在Axios类添加interceptors属性保存请求拦截管理器和响应拦截管理器,并且拼成一条promise链,连续调用。```typescriptimport { AxiosPromise, AxiosRequestConfig, AxiosResponse, Method, RejectedFn, ResolvedFn } from '../types/index'import dispatchRequest from './dispacthRequest'import { InterceptorManager } from './interceptorManager'interface Interceptors {request: InterceptorManager<AxiosRequestConfig>response: InterceptorManager<AxiosResponse>}interface PromiseChain<T> {resolved: ResolvedFn<T> | ((config: AxiosRequestConfig) => AxiosPromise<T>)rejected?: RejectedFn}export default class Axios {interceptors: Interceptorsconstructor() {this.interceptors = {request: new InterceptorManager<AxiosRequestConfig>(),response: new InterceptorManager<AxiosResponse>()}}request(url: string | AxiosRequestConfig, config?: AxiosRequestConfig): AxiosPromise {// 重载if (typeof url === 'string') {if (!config) {config = {}}config.url = url} else {config = url}const chain: PromiseChain<any>[] = [{resolved: dispatchRequest,}]// 请求拦截器,先添加,后调用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 as AxiosPromise}// _requestWithNoDataget(url: string, config?: AxiosRequestConfig) {return this._requestWithNoData('get', url, config)}head(url: string, config?: AxiosRequestConfig) {return this._requestWithNoData('head', url, config)}delete(url: string, config?: AxiosRequestConfig) {return this._requestWithNoData('delete', url, config)}options(url: string, config?: AxiosRequestConfig) {return this._requestWithNoData('options', url, config)}// _requestWithDatapost(url: string, data?: any, config?: AxiosRequestConfig) {return this._requestWithData('post', url, data, config)}put(url: string, data?: any, config?: AxiosRequestConfig) {return this._requestWithData('put', url, data, config)}patch(url: string, data?: any, config?: AxiosRequestConfig) {return this._requestWithData('patch', url, data, config)}_requestWithNoData(method: Method, url: string, config?: AxiosRequestConfig) {return this.request(Object.assign(config || {}, {method,url}))}_requestWithData(method: Method, url: string, data?: any, config?: AxiosRequestConfig) {return this.request(Object.assign(config || {}, {method,url,data}))}}
