zoukankan      html  css  js  c++  java
  • applyMiddleware源码中的闭包

      闭包都是个老掉牙的话题了,这次又提起,是因为重看Redux源码时发现了applyMiddleware里的用法很巧妙。我们先看一个简单的例子。

            var a = (num) => num + 1
            var b = {
                name: (num) => a(num)
            }
    
            a = (num) => num + 5
    
            console.log(b.name(3))

    打印结果是4还是8呢?

    对象b有一个属性name。name是一个方法,函数体里使用了函数a,a是全局作用域的变量,之后a修改了。答案是8。我们不是在作用域里取到变量的值,而是在作用域所对应的执行上下文取到变量的值,并且可能同样的作用域,相同的变量取到的值是不同的。  可以看看这篇文章系列。

    接下来看我们的applyMiddleware源码。

    export default function applyMiddleware(...middlewares) {
      return (createStore) => (reducer, preloadedState, enhancer) => {
        const store = createStore(reducer, preloadedState, enhancer)
        let dispatch = store.dispatch
        let chain = []
    
        const middlewareAPI = {
          getState: store.getState,
          dispatch: (action) => dispatch(action)
        }
        chain = middlewares.map(middleware => middleware(middlewareAPI))
        dispatch = compose(...chain)(store.dispatch)
    
        return {
          ...store,
          dispatch
        }
      }
    }

    一个比较关键的的地方是变量middlewareAPI ,它是一个对象,对象有方法dispatch,该方法内部调用了外部的dispatch。接下来在数组map方法里,该对象作为实参传递。

    我们看thunk中间件源码

    export default function thunkMiddleware({ dispatch, getState }) {
      return next => action =>
        typeof action === 'function' ?
          action(dispatch, getState) :
          next(action);
    }

    middlewareAPI 传递过来的dispatch一直到判断了action是function的时候才进行传递使用,这个时候的dispatch其实是已经增强的dispatch了,即dispatch = compose(...chain)(store.dispatch)这个dispatch了。

    总结起来就是中间件的形参next接受的是原始store.dispatch,而thunkMiddleware({ dispatch, getState })或者说是middleware(middlewareAPI)里的dispatch是增强后的dispatch = compose(...chain)(store.dispatch)这个dispatch了

  • 相关阅读:
    as3.0 网络通信
    flash显示html
    [javascript]对象
    hibernate
    远程服务
    [mysql]笔记1
    [笔记]深入剖析Tomcat-tomcat的默认连接器,servlet容器
    [java]关于访问权限
    [笔记]http权威指南(2)
    [笔记]http权威指南
  • 原文地址:https://www.cnblogs.com/zhansu/p/11294183.html
Copyright © 2011-2022 走看看