文章首发于我的博客 https://github.com/mcuking/bl...

相干代码请查阅 https://github.com/mcuking/bl...

接着上一讲的中间件机制持续讲。
上一讲中咱们实现了redux-thunk中间件,使得加强后的dispatch不仅可能接管对象类型的action,还可能接管函数类型的action。
在此咱们是否可能在结构一个中间件,使得加强后的dispatch还能解决action组成的数组,如下:

export function buyHouse() {    return {type: BUY_House}}export function buyHouseAsync() {    return dispatch => {        setTimeout(() => {            dispatch(buyHouse())        }, 2000)    }}export function buyTwice() {    return [buyHouse(), buyHouseAsync()]}

结构中间件redux-arrThunk

为此咱们决定再结构一个中间件,命名redux-arrThunk,使加强后的dispatch还能解决action组成的数组。代码如下:

const arrThunk = ({dispatch, getState}) => next => action => {    // next为原生的dispatch    // 如果是数组,顺次执行数组中每一个action,参数是dispatch和getState    if (Array.isArray(action)) {        return action.forEach(v=>dispatch(v))    }    // 如果不满足条件,则间接调用下一个中间件(应用next)    // 如果满足条件,则须要从新dispatch(调用dispatch)    // 默认间接用原生dispatch收回action    return next(action)}

中间件叠加应用

因为原理相似第三讲中的redux-thunk,下面的代码并不难,但问题是,咱们如何将这两个中间件叠加起来应用,为此咱们须要批改之前的applyMiddleware函数,使其可能接管多个中间件,并且是的这些中间件可能叠加应用。代码如下:

// applyMiddlewareexport function applyMiddleware(...middlewares) {    return createStore => (...args) => {        // 第一步 取得原生store以及原生dispatch        const store = createStore(...args)        let dispatch = store.dispatch                const midApi = {            getState: store.getState,            dispatch: (...args) => dispatch(...args)        }        // 第二步 将原生dipatch传入中间件进行扩大加强,生成新的dispatch        const middlewaresChain = middlewares.map(middleware => middleware(midApi))        dispatch = compose(...middlewaresChain)(dispatch)        // dispatch = middleware(midApi)(dispatch)        return {            ...store, // 原生store            dispatch, // 加强扩大后的dispatch        }    }}// compose//compose(fn1, fn2, fn3) return为 fn1(fn2(fn3))export function compose(...funcs) {    if (funcs.length === 0) {        return arg => arg    }    if (funcs.length === 1) {        return funcs[0]    }    return funcs.reduce((ret, item) => (...args) => ret(item(...args)))}

比照上一讲中的applyMiddleware,这一次次要是在解决中间件时,对中间件进行了遍历,并且通过compose办法使得多个中间件能够叠加应用,行将fn1, fn2, fn3 转换为 fn1(fn2(fn3))

// 之前dispatch = middleware(midApi)(dispatch)// 之后const middlewaresChain = middlewares.map(middleware => middleware(midApi))dispatch = compose(...middlewaresChain)(dispatch)

因而能够像如下代码一样进行叠加应用多个中间件

import React from 'react'import ReactDOM from 'react-dom'import { createStore, applyMiddleware } from './mini-redux'import { Provider } from './mini-react-redux'import { counter } from './index.redux'import thunk from './mini-redux-thunk'import arrThunk from './mini-redux-arrThunk'import App from './App'const store = createStore(counter, applyMiddleware(thunk, arrThunk))ReactDOM.render(    (        <Provider store={store}>            <App/>        </Provider>    ),    document.getElementById('root'))

其中 const store = createStore(counter, applyMiddleware(thunk, arrThunk)),意味着加强后的dispatch具备如下性能

dispatch(action) = thunk(arrThunk(midApi)(store.dispatch)(action))

至此,咱们的mini-redux就开发实现咯,有任何问题或意见欢送分割我。

相干文章如下:

  • mini-redux 实现原理解说 第一讲
  • mini-redux 实现原理解说 第二讲
  • mini-redux 实现原理解说 第三讲
  • mini-redux 实现原理解说 第四讲