实现redux中间件-洋葱模型
2017-07-27 本文已影响97人
mengxr
//-----------------------------------------------------------------------------
//假设 存在一个核心操作 接收参数coreArg
//建立洋葱模型,包裹N层中间件
//要求:
// 在核心代码执行执之前必须要有序执行中间件
// 核心代码执行后层层返回
// 每个中间件都能接收到coreArg
function receiveMiddleware () {
//拿到中间件队列
let middlewareList = Array.prototype.slice.call(arguments);
//将中间件队列改造为函数层层嵌套形式
//[a,b,c,d] => a(b(c(d(core)))) By reduce
let tiggerPip = middlewareList.reduce((a, b) => (core) => a(b(core)));
let tiggerPipWitchCoreHandler = tiggerPip(() => { console.log('我是核心操作') });
return tiggerPipWitchCoreHandler;
}
const middleware1 = (next) => (lastMDarg) => {
console.log('lm 1 start')
next(lastMDarg);
console.log('lm 1 end')
};
const middleware2 = (next) => (lastMDarg) => {
console.log('lm 2 start')
next(lastMDarg);
console.log('lm 2 end')
};
const middleware3 = (next) => (lastMDarg) => {
console.log('lm 3 start')
next(lastMDarg);
console.log('lm 3 end')
};
let dispatch = receiveMiddleware(middleware1, middleware2, middleware3);
dispatch({ type: 'fff' });
//-----------------------------------------------------------------------------
//增加异步操作
const store = {
status: {name: 'zhangsan'},
getState: () => { return this.status },
dispatch: (arg) => {console.log(`我是核心操作,参数=${arg}`)}
};
function receiveMiddleware () {
//拿到中间件队列
let middlewareList = Array.prototype.slice.call(arguments);
let dispatch = store.dispatch;
let middlewareAPI = {
dispatch: (arg) => { dispatch(arg) },
getState: store.getState,
};
//判断中间件数量
if (middlewareList.length === 0) { return dispatch }
//将核心操作当作参数赋予每个中间件
middlewareList = middlewareList.map((middleware) => middleware(middlewareAPI));
//将中间件队列改造为函数层层嵌套形式
//[a,b,c,d] => a(b(c(d(core)))) By reduce
let tiggerPip = middlewareList.reduce((a, b) => (reallyDispatch) => a(b(reallyDispatch)));
//重写dispatch
dispatch = tiggerPip(store.dispatch);
return dispatch;
}
const middleware1 = (middlewareAPI) => (next) => (lastMDarg) => {
console.log('lm 1 start')
next(lastMDarg);
console.log('lm 1 end')
};
const middleware2 = (middlewareAPI) => (next) => (lastMDarg) => {
console.log('lm 2 start')
next(lastMDarg);
console.log('lm 2 end')
};
const middleware3 = (middlewareAPI) => (next) => (lastMDarg) => {
console.log('lm 3 start')
next(lastMDarg);
console.log('lm 3 end')
};
const supportAsyncMiddleware = (middlewareAPI) => (next) => (lastMDarg) => {
console.log('lm supportAsyncMiddleware start')
if (typeof lastMDarg === 'function') {
lastMDarg(middlewareAPI)
} else {
next(lastMDarg);
console.log('lm supportAsyncMiddleware end')
}
};
let dispatch = receiveMiddleware(middleware1,
middleware2,
middleware3,
supportAsyncMiddleware);
let asyncFun = (middlewareAPI) => {
setTimeout(() => {
let mockGetData = 'im mock data'
middlewareAPI.dispatch(mockGetData)
console.log(middlewareAPI.getState())
}, 3000)
}
dispatch(asyncFun)