使用方式java
const store = applyMiddleware(...middlewares)(createStore)(reducer, initialState)
源码 版本 0.14.0redux
function applyMiddleware() { //1 for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) { middlewares[_key] = arguments[_key]; } //2 return function (createStore) { //3 return function (reducer, preloadedState, enhancer) { //4 var store = createStore(reducer, preloadedState, enhancer); var _dispatch = store.dispatch; var chain = []; //5 var middlewareAPI = { getState: store.getState, dispatch: function dispatch(action) { return _dispatch(action); } }; chain = middlewares.map(function (middleware) { return middleware(middlewareAPI); }); //6 _dispatch = _compose2['default'].apply(undefined, chain)(store.dispatch); return _extends({}, store, { dispatch: _dispatch }); }; }; }
applyMiddleware方法主要是对redux的dispacth方法进行封装设计模式
原理数组
const _dispatch = store.dispatch; store.dispatch = function (action) { console.log('加强功能'); _dispatch(action); console.log('加强功能'); }
原理很简单就是将store的dispatch进行替换,换成一个功能加强了可是具备dispach功能的新函数请输入代码
原理和java设计模式中的 装饰者模式很像,旨在加强功能,但不改变接口app
接下来具体分析 applyMiddleware 函数函数
1. 代码//1spa
for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) { middlewares[_key] = arguments[_key]; }
因为第一个框号(...middlewares)里面的参数能够是多个中间件(m1,m2,m3)这种类型,或者是一个中间件数组
因此这里经过 遍历 js函数的 arguments 属性将全部的参数取出放到 middlewares 数组中设计
2. 代码//2 //3code
applyMiddleware 这个函数实际上是一个 柯里化 的函数,
柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,
而且返回接受余下的参数且返回结果的新函数的技术中间件
这里有几个关键字 多个参数 单一参数 返回接受余下参数的函数 返回结果
//举例
function count(a,b,c) { return a+b+c; } count(1,2,3);
咱们看到 count接受多个参数,这里是三个,最后返回了计算结果,接下来把它柯里化
function count(a) { return function(b) { return function(c) { return a+b+c; } } } count(1)(2)(3);
咱们看到区别在于 柯里化 后函数只接受一个参数,返回了接受剩余参数的函数,因此要分屡次调用
3. //代码4
var store = createStore(reducer, preloadedState, enhancer); var _dispatch = store.dispatch; var chain = [];
这里作了三件事情,1 用reducer建立了一个 store,2 var _dispatch = store.dispatch; 将原来的
dispatch方法保存了起来,由于后咱们要覆盖 dispach 但又要用到原始的dispatch的功能,因此保存
3 var chain = [];咱们的中间件也是一个 柯里化 的函数,这个数组用来保存中间件接受第一个参数
后返回的函数
4. //代码5
var middlewareAPI = { getState: store.getState, dispatch: function dispatch(action) { return _dispatch(action); } }; chain = middlewares.map(function (middleware) { return middleware(middlewareAPI); });
middlewareAPI 对象有两个成员 getState和dispatch,因为这两个成员咱们会在中间件里面用到
因此咱们要将它们传递给中间件 调用 middlewares.map 方法,middlewares是一个数组,map方法
接受一个函数,这个函数的第一个参数就是 middlewares 数组的成员,咱们调用map方法会遍历
middlewares数组,将它的每个成员传递给 成员处理函数,最终返回了一个由 处理函数返回值
组成的数组,经过以上代码咱们就能够在中间件中使用getState,和dispatch这两个方法了
5. //代码6
_dispatch = _compose2['default'].apply(undefined, chain)(store.dispatch); return _extends({}, store, { dispatch: _dispatch });
这里作的事情就是咱们开始的原理中作的事情 将 disatch 加强而且替换掉store中的dispatch,替换后的dispach中会调用中间件,咱们看到返回值_extends 是一个函数,接收store,和加强后的_dispatch,用来替换本身的 dispatch方法