场景,页面中有多个子模块(如A、B、C),会发送同一个http请求(多个模块发送的http请求参数相同)。这些模块彼此独立,页面中可能有些时候用到A、B模块,有些时候用到B、C模块。模块加载有先后顺序,且不固定,A、B、C模块都有可能第一个加载。
项目是通过更改Promise chain + cache的模式实现从图1到图2的模式,避免重复发送http请求。
图1 ↑
图2 ↑
如果是下面的图3到图4,用防抖解决。
图3 ↑
图4 ↑
实际项目是一个vue项目,由于模块A、B、C互相独立,且层级关系并不同级,在这个场景里,入口页面发一次请求,做数据处理再分发给三个模块这样数据传递模式不合适。
考虑下来,在vue store(vuex)的actions中发送http请求,处理数据(初加工,加工公共部分),缓存数据(交给vuex state)这种方式,子模块自行取用。
按照这个思路实现,要解决下面几个问题:
1、判断是相同的请求。
2、缓存结果,func1来请求数据时,在缓存中查找结果是否存在;如果结果存在,子模块请求数据时,不再发送第二次http请求。
3、定时清理缓存。(非必须)
1、判断相同的请求,最完善的实现方式当然是hash,这里不是本文要讲的重点,略。
2、缓存结果,这里的结果不是http请求返回之后的数据,而是http已经发送的状态。
说明:
在第一次发送http请求之后,这个http请求的状态(如pending状态的Promise实例)就必须即刻进入缓存中。不能等待请求完成之后,再将http请求的结果放入缓存中。
如果是等待http完成后将http的结果放入缓存,第1个func1触发http1请求发送未返回结果的阶段,缓存中没有http1的结果。此时如果第2个func1到来,第2个func1依然可以触发http1发送。
实现:
直接上代码
重点在actions中的new Promise操作。还要注意如果http请求失败,要通过DELETE_HTTP_RES操作来清空这个字段。
完结。
代码示例见
https://github.com/DiracKeeko...
同步更新到自己的语雀
https://www.yuque.com/diracke...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。