1. 事件起因
??之前做一個駕照考題的專案,有一個這樣的問題,每當我選好了科目和駕照型別后(如圖1),點擊開始考試就會跳到考試頁面(Test.tsx),并且在Test組件中對我架設的中間層發起請求獲取資料(如圖2),
??如果用戶手滑的話不小心點到了左上角的回傳,或者狠狠地把螢屏往右滑動一下的話,都會回傳到首頁,再重新點擊開始考試后進入到Test組件內又會重新發送請求獲取隨機題目,重新渲染題目串列,這樣的話比較消耗性能吧,也是用戶不愿意看到的,
??
?
??????????????圖1
?
圖2
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設計模式》 張容銘 著
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/501127.html
標籤:其他
上一篇:設計模式之橋接模式
