applyMiddleware源码分析redux中的中间件机制强大方便。使用redux中间件,我们可以实现日志记录、异步调用等非常实用的功能。redux的中间件主要是通过applyMiddleware模块实现的。接下来,我们就好好看看这个模块有什么神奇的力量吧。关于中间件的使用,不懂的同学需要参考redux文档进行学习。在分析中间件源码之前,我们需要了解一件事:redux源码中是如何调用中间件模块的?只有理解了这个问题,才能知道每个参数代表什么。中间件的本质是作为增强器存在的。因此,它通过createStore方法传递到redux的内部。【createStore源码分析】()中有这么一段代码:if(typeofenhancer!=='undefined'){if(typeofenhancer!=='function'){thrownewError('Expectedtheenhancertobeafunction.')}returnenhancer(createStore)(reducer,preloadedState)}从这段代码中,我们很容易看出中间件模块是一个高阶函数。它的函数签名可以表示如下:constapplyMiddleware=(listofeachmiddleware)=>(createStore(createstore))=>(reducer(reducercollection),preloadedState(initialstate))=>{}理解上面的问题,还有一个问题我们需要知道——redux中间件的形式是什么?这里,我们选择了处理异步的中间件redux-thunk的源码,给大家讲解一下。(看到代码只想说,shit,shit,shit)。functioncreateThunkMiddleware(extraArgument){return({dispatch,getState})=>next=>action=>{if(typeofaction==='function'){returnaction(dispatch,getState,extraArgument);}}返回下一个(行动);};}constthunk=createThunkMiddleware();thunk.withExtraArgument=createThunkMiddleware;导出默认thunk;我们应该如何在redux中使用它?createStore(reducers,applyMiddleware(thunk))到这里,我们就知道了redux是如何使用中间件的。接下来,我们将详细说明redux的源码内部是如何处理中间件的。为了帮助您更好地理解,让我告诉您一些事情。redux的中间件都遵循一定的规范。不管是官方的中间件还是我们以后需要自己写的中间件,它的函数签名是一定的。也就是说,中间件的基本格式是一样的,接收到的参数也是通过redux注入的。下面是redux中间件的基本格式:constreduxMiddleware=({dispatch,getState}[简化store])=>(next[前一个中间件的dispatch方法])=>(action[实际派发的action对象])=>{}至此,我们可以深入研究redux中间件的源码:exportdefaultfunctionapplyMiddleware(...middlewares){//middlewares是我们传递给applyMiddlewarez函数的一系列中间件函数(...args)=>{//createStore是redux用来创建store的方法,args===[reducers,preloadedState]。下面这句在中间件内部,使用我们传递的参数创建一个store对象//注意:这块没有通过enhancer,所以返回的是我们经常使用的store对象conststore=createStore(...args)//获取store对象的dispatch方法letdispatch=store.dispatch//保存中间件函数的第二层函数letchain=[]//传递给中间件第一层函数的参数,constmiddlewareAPI={getState:store.getState,//重写dispatch方法,其实就是store.dispatch(...args)dispatch:(...args)=>dispatch(...args)}/***关注Please详细解释一下这块*假设我们传递给applyMiddleware函数的中间件是*applyMiddleware(*f1=>g1=>h1(...arg)=>{},*f2=>g2=>h2(...arg)=>{}*)*运行下面这行代码后,链中保存的内容为*chain=[g1=>h1(...arg)=>{},g2=>h2(...arg)=>{}]*/chain=middlewares.map(middleware=>middleware(middlewareAPI))/***当我们将chain传入compose时,根据我们对compose的分析,*compose(...chain)(store.dispatch)is:*g1(h2(...arg))=>h1(...arg)**也就是说,根据上面的形式,下面的didispatch和h1函数是一样的,所以h1的参数就是我们需要dispatch的action。当我们调用dispatch的时候,其实就相当于调用了h1(action),而在h1内部,这个action是由g1生成的参数*由h2进行dispatch,所以这个时候action是传递给h2内部的,而h2的参数由g2的参数分发,也就是实际传入的store.dispatch,逐层传入。层层输出形成了我们强大的中间件机制*/dispatch=compose(...chain)(store.dispatch)//返回的也是一个store对象return{...store,//这个dispatch是其实,每个中间件的底层(第三层)哪个函数是由一个ring函数组成一个dispatch}}}这是对applyMiddleware源码的整体解读,水平有限,欢迎拍砖。后续源码解读和测试示例可参考:redux源码解读仓库
