02 - redux 插件的实现

225 阅读1分钟

redux 插件的实现

1、插件使用

const store = createStore(countReducer, applyMiddleware(thunk, logger))

// applyMiddleware(thunk, logger) 就是引入插件
// store内部

export default function createStore(reducer, enhancer) {
	if (enhancer) { // 插件
		return enhancer(createStore)(reducer) // 这里引入插件
	}
	
	// ....
	
	return {
		getState,
		dispatch,
		subscribe
	}
}

2、插件实现

1、利用闭包,传入操作权限返回一个函数

2、这个函数

// 支持日志输出
export function logger({ getState }) {
	return (next) => {
		console.log('logger生成')
		return (action) => {
			console.log(action.type + ':logger执行')
			//sy-log
			const prevState = getState()
			console.log('prev state', prevState) //sy-log
			const returnValue = next(action)
			const nextState = getState()
			console.log('next state', nextState) //sy-log
			return returnValue
		}
	}
}

// 支持传入函数
export function thunk({ dispatch, getState }) {
	return (next) => {
		console.log('thunk生成')
		return (action) => {
			console.log('thunk执行')
			if (typeof action === 'function') {
				return action(dispatch, getState)
			}
			const x = next(action)
			console.log('thunk后置')
			return x
		}
	}
}

function isPromise(promise) {
	return typeof promise === 'object' && /Promise/g.test(promise.toString())
}

// 支持promise执行  传入的promise返回必须是 包含type了,且该promise不会继续走日志部分
export function promise({ dispatch }) {
	return (next) => (action) => {
		return isPromise(action) ? action.then(dispatch) : next(action)
	}
}

// 这里实际实现,方法 (ops操作曲线) => 函数1
// 函数1 为 传入一个dispatch方法返回一个加工后dispatch函数



applyMiddleware 加入插件的方法

export function applyMiddleware(...middlewares) {
	return (createStore) => (reducer) => {
		const store = createStore(reducer) // 创建存储器
    let dispatch = store.dispatch // 获取派发‘
    // 提供操作权限
		const midApi = {
			getState: store.getState,
			dispatch: (action, ...args) => dispatch(action, ...args)
    }
    
    // 这里每步按照reduce的策略都是传入一个dispatch函数
    // 返回一个dispatch函数
    // (next) => (action)=> {  
    //    作前置处理
    //    const x =next(action) 
    //    作后置处理
    //    return x
    // }
    const middlewareChain = middlewares.map((middleware) => middleware(midApi))
    
		dispatch = compose(...middlewareChain)(store.dispatch)
		return {
			...store // 加强版的dispatch
		}
	}
}

3、compose 方法

const comreducer = (a, b) => (...args) => a(b(...args))

function compose(...args) {
	if (args.length === 0) {
		return null
	}
	return args.reduce(comreducer)
}

思考题

applyMiddleware(thunk, logger) 这样导致执行的顺序是怎样