1

(前端)「备忘录」设计模式在项目开发中的应用 - 红果园园长

 1 year ago
source link: https://www.cnblogs.com/lingda-blogs/p/16556254.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

(前端)「备忘录」设计模式在项目开发中的应用

1. 事件起因

  之前做一个驾照考题的项目,有一个这样的问题,每当我选好了科目和驾照类型后(如图1),点击开始考试就会跳到考试页面(Test.tsx),并且在Test组件中对我架设的中间层发起请求获取数据(如图2)。

  如果用户手滑的话不小心点到了左上角的返回,或者狠狠地把屏幕往右滑动一下的话,都会返回到首页,再重新点击开始考试后进入到Test组件内又会重新发送请求获取随机题目,重新渲染题目列表,这样的话比较消耗性能吧,也是用户不愿意看到的。

  

2896880-20220805233854234-324376549.png

2896880-20220805234122398-806208061.png

 

2. 解决方案

  利用「备忘录」设计模式。

  实现思路: 备忘录其实说白了就是做一次缓存,在发起请求之前先判断缓存中是否有我要请求的数据,如果有就走缓存,如果没有就重新请求,请求完了之后再把请求到的数据设置进缓存中。

  代码如下:

  src/QuesMemo/index.ts:

// 封装一个关于考题的备忘录类, 实例的cache对象中存放所有关于考题的数据class QuesMemo { cache: any; static instance: any; constructor() { // cache中存放所有缓存的数据 this.cache = {}; } static getInstance() { if(!QuesMemo.instance) { Object.defineProperty(QuesMemo, 'instance', { value: new QuesMemo() }); } return QuesMemo.instance; } // 将数据增添至信息缓存的方法 addMemo(key: string, value: Array<any>) { this.cache[key] = value; }} export default QuesMemo.getInstance() as object;

  下面来到Test组件内,在请求之前先判断下缓存中有没有我要请求的数据,代码如下:

  src/views/Test.tsx:

// 这个是自定义的hook, 里面就是做了请求数据以及拿到数据后设置当前问题curQuestion的操作, 在Test组件内调用这个hook即可export function useCurQuestion(): [ IQueryData | null, any ] { const subject: SUBJECTS = useSelector((state: IState) => state.curSubject); const model: MODELS = useSelector((state: IState) => state.model); const [ curQuestion, setCurQuestion ] = useState<IQueryData>(null); const dispatch: Dispatch = useDispatch(); useEffect(() => { // 开始判断cache缓存中是否有我所需要的考题数据, 考题数据的key我定义为 subject-model 的形式 if(quesMemo.cache[`${ subject }-${ model }`]) { // 如果有考题数据那我就走缓存 let result: IQueryData[] = quesMemo.cache[ `${ subject }-${ model }` ]; dispatch({ type: types.SET_QUERY_LIST, payload: result }); setCurQuestion(result[0]); // 重新进入Test从第一题开始答 }else { // getQueries是向node中间层发起请求获取数据哈 getQueries({ subject, model }).then(res => { console.log('res: ', res); dispatch({ type: types.SET_QUERY_LIST, payload: res.result }); setCurQuestion(res.result[0]); // 获取到了新数据后再把数据丢入缓存 quesMemo.addMemo( `${ subject }-${ model }`, res.result ); }); } }, [ subject, model, dispatch ]); return [ curQuestion, setCurQuestion ];}

  以上就是备忘录设计模式的大致使用了,感觉思路挺简单的,就是做了一次缓存,请求之前判断有数据就走缓存,没数据就重新请求再丢进缓存。

  参考书籍 《JavaScript设计模式》 张容铭 著


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK