仓管,仓管!!!我们需要一双翅膀
回忆哈!出货单是action, reducer是货物, dispatch是仓管。
问题来了,现在的仓管职责太单一了,收获,发货,通知。
现在我们要求仓管多才多艺,比如在收货前唱首激昂的歌曲(打印日志), 收完货吟唱首抒情的小诗。就好比我们公司,没得点才艺都进不来。不然年会谁去呀?^V^
小小的我们,小小的才艺
一句代码教你如何添加才艺:
// 假设store仓库
let dispatch = store.dispatch;
function logger(action) {
console.log('我心中有一首歌');
dispatch(action);
console.log('我再吟一首诗');
}
// 再重新赋值,既保留了原来的,功能,又在之前的功能上增强了。
dispatch = logger
仓管才艺注册中心
接下来我们把注册中间件的方法叫做applyMiddleware。
// 第一步肯定是传入中间件
function applyMiddleware(middleware) {
// 传入仓库创建方法
return function(createStore) {
// 创建仓库,我们需要reducer
return function(reducer) {
// 返回仓库
let store = createStore(reducer);
let dispatch;
let middlewareApi = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
middleware = middleware(middlewareApi);
dispatch = middleware(store.dispatch);
return {
...store,
dispatch
}
}
}
}
然后我们写一个自己的中间件
function logger({getState, dispatch}) {
// dispatch是新包装的dispatch
return function(next) {
// next是下一个中间件,没有就是原来的dispatch
return function(action) {
console.log('我心中有一首歌');
next(action);
console.log('我再吟一首诗');
}
}
}
从上面我们看出只处理了一个中间件,那么多个中间件,如何处理。那就是包装。举个小栗子。
function add1(str) {
return str
}
function add2(str) {
return str + ':'
}
function add3(str) {
return str + 'hello'
}
// 现在我们希望,add1的结果add2的参数,add2的结果当add3的参数
add3(add2(add1('王先生')))
那么我们写个方法来聚合,就叫compose好了
function compose(...fns) {
if(fns.length==1) return fns[0];
return fns.reduce((preFn, curFn) => {
return (...arg) => {
return curFn(preFn(...arg))
}
})
}
优化仓库注册中心
把我们之前的代码组织哈,就是我们完整的中间件注册了。
function applyMiddleware(middlewares) {
// 传入仓库创建方法
return function(createStore) {
// 创建仓库,我们需要reducer
return function(reducer) {
// 返回仓库
let store = createStore(reducer);
let dispatch;
let middlewareApi = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
middlewares = middlewares.map(middleware => middleware(middlewareApi));
dispatch = compose(...middlewares)(store.dispatch);
return {
...store,
dispatch
}
}
}
}
流行时尚才艺-中间件
thunk中间件
function thunk({getState, dispatch}) {
return function(next) {
return function(action) {
if(typeof action === 'function') {
action(dispatch, getState);
}else{
next(action);
}
}
}
}
promise中间件
function redux-promise({getState, dispatch}) {
return function(next) {
return function(action) {
if(action.then && typeof action.then === 'function') {
action.then(dispatch);
}else if(action.payload&& action.payload.then&& typeof action.payload.then == 'function'){
action.payload.then(payload => dispatch({...action, payload}), payload => dispatch({...action, payload}));
}else{
next(action);
}
}
}
}
总结
实践出真理,中间件给我们更多方式去处理代码,像处理异步,打印日志等。