背景
以下是手写系列内容预告,初步计划一周一个主题。
- 手写Promise、Promise.all、Promise.race
- 手写发布订阅模式
- 手写简易Redux
- 手写简易模块加载器
- 手写简易模块打包器
- 手写简易React
- 手写简易React Hooks
- ......(根据小伙伴的提议待定)
简易发布订阅模式
上篇文章我们实现了发布订阅模式,这里再重现一次代码,写法更简洁一些
function createEventHub() {
const map = {}
return {
on(type, handler) {
map[type] = (map[type] || []).concat(handler)
},
fire(type, data) {
map[type] && map[type].forEach(handler => handler(data))
}
}
}
let EventHub = createEventHub()
EventHub.on('hello', data => console.log(data))
EventHub.fire('hello', 'jirengu.com')
改造发布订阅实现Redux雏形
function createStore(initState) {
let state = initState
let handlers = []
return {
getState() {
return state
},
changeState(newState) {
state = newState
handlers.forEach(handler => handler())
},
subscribe(handler) {
handlers.push(handler)
}
}
}
let store = createStore({msg: 'jirengu'})
store.subscribe(() => {
let state = store.getState()
console.log(state)
})
store.changeState({msg: '饥人谷'})
以上代码依然是发布订阅模式,只不过把 on 换成了 subscribe,把 fire 换成了 changeStage。回调函数列表的触发不再区分事件类型。
Redux完善
function createStore(reducer) {
let state
let handlers = []
return {
getState() {
return state
},
dispatch(action) {
state = reducer(state, action)
handlers.forEach(handler => handler())
},
subscribe(handler) {
handlers.push(handler)
}
}
}
function counter(state = 10, action) {
switch (action.type) {
case '+':
return state + action.val
case '-':
return state - action.val
default:
return state
}
}
let store = createStore(counter)
store.subscribe(() => console.log(store.getState()))
store.dispatch({type: '+', val: 10})
store.dispatch({type: '-', val: 10})
把直接通过 changeState 修改状态改成通过 dispatch 一个 action 来触发,把state的修改规则通过调用createStore传递的reducer方法来实现。