二話不說 輪子我都會造 還怕你面試問嗎? 一天造一個輪子,幹就完了。前端
(計劃趕不上變化 隨時迭代 歡迎留言 隨時摸魚)git
若是編寫一個複雜的前端程序,不太可能讓組件各自爲政。狀態和行爲邏輯都分散在各自組件內部,很難統一管理,那也就很難作大.好比: 你們想一想作一個在線版的Excel或者PS 又或者後面咱們要寫的VSCode應該怎麼作?裏面的各類組件互動,Undo、Redo、行爲記錄怎麼作?在線版王者榮耀如何播放視頻錄像,如何直播?github
要完成這樣的功能須要三個要求:面試
單一數據源 : 就是狀態數據統一放在一塊兒算法
保持狀態只讀 : 狀態數據誰都不能改,須要改的話找管理員贊成修改設計模式
數據修改使用純函數 : 修改數據的方法也要統一管理,這樣容易回退,記錄復現、時間旅行markdown
狀態通知 : 狀態修改能夠獲得通知,固然不少人都要收聽這個最好使用訂閱發佈模式。這個不是剛需,我就一個地方用用怎麼了。誰變了我整個視圖都刷新。因此我們拆解開,此次只知足能觸發狀態變動通知就好了。後面設計模式我們在慢慢盤這些東西。app
it("基本功能 訂閱通知 改變狀態", () => {
const { createStore } = require("../index");
const mockFn = jest.fn();
const store = createStore(reducer);
// 創建響應訂閱
store.effect(mockFn);
store.dispatch({
type: "clear",
});
// store.dispatch({ type: "add", payload: 1 });
const calls = mockFn.mock.calls;
// 斷言 mock方法只調用一次
expect(calls.length).toBe(1);
expect(store.getState().num).toBe(0);
});
複製代碼
超級簡單是吧 我就解釋了框架
module.exports.createStore = (reducer, preloadedState) => {
let currentReducer = reducer; //reducer函數
let currentState = preloadedState; //默認state
let effective
return {
getState() {
return currentState;
},
dispatch(action) {
currentState = currentReducer(currentState, action);
// 觸發通知
effective()
},
effect(fn) {
effective = fn;
},
};
};
複製代碼
OK 任務完成異步
主要是咱們拆解了和統一狀態管理不強綁定的問題。
固然這個實現訂閱發佈模式就好了
大概兩個方案Thunk方案 和 Promise方案 這個等咱們後續分別造完Thunk和 Promise輪子再說
這個須要引入中間件洋蔥圈模型也就是實現責任鏈模式
這個須要實現備忘錄設計模式