全局处理——axios拦截器
1. loading效果(不美观;可能loading套loading)
2. 把完全相同的请求给拦截掉(请求方法、地址、参数、携带数据、页面哈希)
缺点:错误处理逻辑仍然会执行多次;请求来自同一页面时后调接口的组件就无法拿到正确数据
3. 拦截相同请求时不直接把请求挂掉,而是先给它挂起,等到最先发出去的请求拿到结果再把成功或失败的结果共享给后面到来的相同请求(发布订阅模式)
这里用await new Promise,仔细想想其实并不是为了后续then来解决,而是将这个promise里的resolve和reject的“生命周期”给“延长”了(作为cb存储在event_bus[reqKey]里),这样才使得首次请求完成后触发emit后能够利用resolve/reject“解决”58行的res,进而进入61行(这里的理解:
就说res只有resolve了才会继续return Promise.reject({});如果reject了就不执行下面的return Promise.reject({})了而是直接返回reject(res);如果都不采用,即不“解决”则t处于挂状态
)
然后两个Promise.reject都会进入响应拦截器的(error) => {}处理逻辑(gpt说是直接走axios () .then().catch()的catch了???config => {}里Promise.reject到底走哪条路??)
总结: 首次请求——成功走第86行(emit(resolve)后相同重复请求return Promise.reject({type,res}),进入110行)、87行结果,失败走第89行、114行(emit(reject)后相同重复请求return Promise.reject({type,res}),进112行)、128行结果
延伸考虑:
网上还有些在拦截器里做防抖处理的,我觉得这并不合适。想象这样一个我们的确需要在短时间内重复请求的场景:同一页面的多个组件用到相同接口(即此请求不是单一事件源触发的),如果用防抖那就只有最后一个发起请求的组件能拿到数据了,这显然是不合理的,节流类似。所以我们最好还是采取多个请求返回同一份结果的做法
还有一点,对于即时性要求比较高的接口我们要做特殊处理,比如后端数据有时候会实时更新,或者对于类似巡检之类的和时间强关联的需求来说,这个拦截要单独做)