redux中间件的源码的一些理解

441 阅读1分钟


这是redux应用了middleware之后的处理事件的流程图,这跟node中的中间件的功能如出一辙,下面我们来看它的源码是如何实现的

function applyMiddleware() {
  for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {
    middlewares[_key] = arguments[_key];
  }

  return function (createStore) {
    return function (reducer, preloadedState, enhancer) {
      var store = createStore(reducer, preloadedState, enhancer);
      var _dispatch = store.dispatch;
      var chain = [];

      var middlewareAPI = {
        getState: store.getState,
        dispatch: function dispatch(action) {
          return _dispatch(action);
        }
      };
      chain = middlewares.map(function (middleware) {
        return middleware(middlewareAPI);
      });
      _dispatch = _compose2['default'].apply(undefined, chain)(store.dispatch);

      return _extends({}, store, {
        dispatch: _dispatch
      });
    };
  };
}

只有二十多行的代码,却非常精简 middleware的设计有点特殊,是一层层包裹的匿名函数,

串联性:是函数式编程中的curry的实现,利用了curry函数具有延迟执行的特性,配合compose函数形成管道数据链

 chain = middlewares.map(function (middleware) {
        return middleware(middlewareAPI);
      });
      _dispatch = _compose2['default'].apply(undefined, chain)(store.dispatch);

最后会形成_dispatch=mid1(mid2(mid3(...(store.dispathch)))),将最原始的dispatch进行了一个功能的增强

共享store:在中间件的执行过程中,store还是旧的,利用函数闭包的特性,保证后面拿到的store都是最新的

var middlewareAPI = {
        getState: store.getState,
        dispatch: function dispatch(action) {
          return _dispatch(action);
        }
      };
      chain = middlewares.map(function (middleware) {
        return middleware(middlewareAPI);
      });

所以我们通常些构建store的时候可以这么写:

const store = applyMiddleware(mid1, mid2, mid3...)(createStore)(reducer, null)

这正好是对上面三层嵌套的实现