「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」
createStore
createStore利用发布订阅模式将数据保存,修改,并通知订阅订阅方法;
问题1
什么是发布订阅?
谁发布,谁订阅
function createStore(reducer) {
let currentState = null;
let dispatchListener = [];
function getState() {
return currentState;
}
function dispatch(action) {
currentState = reducer(currentState, action);
dispatchListener.forEach((listener) => listener());
}
function subscribe(listener) {
dispatchListener.push(listener);
}
dispatch('___redux-------');
return {
getState,
dispatch,
subscribe,
};
}
export default createStore;
applyMiddleware
// 本函数是干嘛的?
// 增强dispatch的
export default function applyMiddleware(...middlewares) {
//不确定有多少个中间件,所以使用...对象展开符
//再看看这函数在createStore文件中的用法,
// enhancer(createStore)(reducer) 函数柯里化
// 看看,这是人想出来的用法吗???
// 人家调用两次,你不得返回两层函数吗?
// 所以就有了一下代码
return (createStore) => {
return (reducer) => {
//有了createStore和reducer,是不是可以得到store?
// 这行代码总是很眼熟的吧
const store = createStore(reducer);
//为啥要拿store?因为要增加dispatch啊,dispatch在store中呀
//然后呢??到这里其实我是没思路的,但是看看applyMiddleware的参数,middleware还没用呢,所以下面的代码应该和middleware有关;
let dispatch = store.dispatch;
// 然后执行middleware
const middlewareAPI = {
getState: store.getState,
dispatch: (action, ...args) => dispatch(action, args),
};
//执行的时候,里面需要getState和dispatch方法,所以将这两个参数传入中间件;
console.log('middleware', middlewares);
const chain = middlewares.map((middleware) => middleware(middlewareAPI));
// 再执行一遍,又是函数柯里化
dispatch = compose(...chain)(store.dispatch);
console.log(typeof dispatch, dispatch);
return {
...store,
dispatch,
};
};
};
}
function compose(...funcs) {
if (funcs.length === 0) return (args) => args;
if (funcs.length === 1) return funcs[0];
return funcs.reduce((a, b) => {
return (...args) => {
return a(b(...args));
};
});
}
放在一个文件中,体会一下
function reducer(state = 1, action) {
switch (action.type) {
case 'add':
return state + 1
default:
return state
}
}
function thunk({ dispatch, getState }) {
return function (next) {
return function (action) {
if (typeof action === 'function') {
return action(dispatch, getState)
}
return next(action)
}
}
}
function applyMiddleware(...middlewares) {
return function (createStore) {
return function (reducer) {
const store = createStore(reducer)
let dispatch = store.dispatch
const middleAPI = {
dispatch: (...args) => dispatch(...args),
getState: store.getState,
}
const chian = middlewares.map((middleware) => middleware(middleAPI))
dispatch = compose(...chian)(store.dispatch)
return {
...store,
dispatch,
}
}
}
}
function compose(...funcs) {
if (funcs.length === 0) return (args) => args
if (funcs.length === 1) return funcs[0]
return funcs.reduce(
(a, b) =>
(...args) =>
a(b(...args))
)
}
// createStore
function createStore(reducer, enhancer) {
if (enhancer) {
return enhancer(createStore)(reducer)
}
let currentState = undefined
let dispatchListener = []
function getState() {
return currentState
}
function dispatch(action) {
currentState = reducer(currentState, action)
dispatchListener.forEach((listener) => listener())
}
function subscribe(listener) {
dispatchListener.push(listener)
return function () {
const idx = dispatchListener.indexOf(listener)
dispatchListener.splice(idx, 1)
}
}
dispatch({ type: 'redux-init' })
return {
getState,
dispatch,
subscribe,
}
}
const store = createStore(reducer, applyMiddleware(thunk))
store.subscribe(() => {
result = store.getState()
console.log('result2', result)
})
let result = store.getState()
console.log('result1', result)
store.dispatch({ type: 'add' })
store.dispatch((dispatch) => {
console.log('我执行了吗?', dispatch)
setTimeout(() => {
dispatch({ type: 'add' })
}, 1000)
})