kredux.js createStore实现 和 applyMiddleware 实现
export function createStore(reducer,enhancer) {//如果存在enhancerif(enhancer) {return enhancer(createStore)(reducer)}let currentState = undefined;const currentListeners = []; //回调函数数组function getState() {return currentState;};//更新状态function dispatch(action) {//修改currentState = reducer(currentState,action)//变更通知currentListeners.forEach(v=>v())return action;}function subscribe(cb) {currentListeners.push(cb);};//初始化状态dispatch({type: '@IMOCKKDEDDSDE'})return {getState,dispatch,subscribe}};export function applyMiddleware(...middlewares) {return createStore => (...args) => {// 先完成之前的 createStore 工作// debuggerconst store = createStore(...args);// 原先的 dispatchlet dispatch = store.dispatch;// 传递给中间件函数的参数const midApi = {getState: store.getState,dispatch: (...args) => dispatch(...args),}//将来中间件函数签名如下 : function({}) {}// debuggerconst chain = middlewares.map(mw => mw(midApi));// 强化dispatch, 让他可以循序执行中间件函数dispatch = compose(...chain)(store.dispatch);//返回全新store, 仅更新强化过的dispatchreturn {...store,dispatch}}}export function compose(...funcs) {// debuggerif(funcs.length === 0) {return arg=>arg;}if(funcs.length === 1) {return funcs[0];}// 聚合函数数组为一个函数 [fn1,fn2] = fn2(fn1())return funcs.reduce((left,right)=>(...args)=>right(left(...args)))}
测试代码
import React, { Component } from 'react'import {CreateStore, applyMiddleware} from './kredux';const counterReducer = function(state=1,action) {switch (action.type) {case 'add':return state +1;case 'minus':return state - 1;default:return state}}//自定义logger中间件function logger() {return dispatch=>action=> {console.log(action.type+'我执行啦')return dispatch(action)}}// 换种写法const thunk = ({dispatch,getState})=>dispatch=>action=>{if(typeof action === 'function') {action(dispatch,getState)}return dispatch(action)}const store = CreateStore(counterReducer,applyMiddleware(logger,thunk))export default class MyTestRedux extends Component {componentDidMount() {store.subscribe(()=>this.forceUpdate())}render () {return (<div><h3>测试</h3><h5>{store.getState()}</h5><button onClick = {()=>store.dispatch({type:'add'})}>加一下</button><button onClick = {()=>store.dispatch({type:'minus'})}>减一下</button><button onClick = {()=>store.dispatch(function(){setTimeout(()=>{store.dispatch({type:'add'})},1000)})}>异步加一下</button></div>)}}
koa2 洋葱模型
async function fn1(next) {console.log('fn1')await next();console.log('end fn1')}async function fn2(next) {console.log('fn2')await next();console.log('end fn2')}async function fn3(next) {console.log('fn3')await next();console.log('end fn3')}function compose2(middlewares){return function() {//执行第一个return dispatch(0)function dispatch(i) {let fn = middlewares[i]if(!fn){return Promise.resolve()}return Promise.resolve(fn(function next(){//执行下一个return dispatch(i+1)}))}}}const middlewares = [fn1,fn2,fn3];const finalFn = compose2(middlewares)finalFn()
