wordpress资源站源码,网站规划与建设课设报告,金州新区规划建设局网站,宁波智能模板建站Redux的中间件#xff08;Middleware#xff09;遵循了即插即用的设计思想#xff0c;出现在Action到达Reducer之前#xff08;如图10所示#xff09;的位置。中间件是一个固定模式的独立函数#xff0c;当把多个中间件像管道那样串联在一起时#xff0c;前一个中间件不… Redux的中间件Middleware遵循了即插即用的设计思想出现在Action到达Reducer之前如图10所示的位置。中间件是一个固定模式的独立函数当把多个中间件像管道那样串联在一起时前一个中间件不但能将其输出传给下一个中间件作为输入还能中断整条管道。在引入中间件后既能扩展Redux的功能也能增强dispatch()函数适应不同的业务需求例如通过中间件记录日志、报告奔溃或处理异步请求等。图10 中间件管道一、开发模式 在设计中间件函数时会遵循一个固定的模式如下代码所示使用了柯里化、高阶函数等函数式编程中的概念。function middleware(store) {return function(next) {return function(action) {return next(action);};};
}middleware()函数接收一个Store实例返回值是一个接收next参数的函数。其中next也是一个函数用来将控制权转移给下一个中间件从而实现了中间件之间的串联它会返回一个处理Action对象的函数。由于闭包的作用在这最内层的函数中依然能调用外层的对象和函数例如访问action所携带的数据、执行store中的dispatch()或getState()方法等。示例中的middleware()函数只是单纯的将接收到的action对象转交给后面的中间件没有对其做额外的处理。 之所以将中间件函数写成层层嵌套的模式有以下几个原因。1扩展Redux需要遵循函数式编程的设计思想。2柯里化让中间件更容易处理数据流即便于形成数据处理管道。3每个中间件的职责单一即函数代码尽量少通过嵌套组合完成复杂功能。 利用ES6中的箭头函数能将middleware()函数改写得更加简洁如下所示。const middleware store next action {return next(action);
};
二、applyMiddleware() Redux提供了组织中间件的applyMiddleware()函数在阅读过此函数的源码如下所示之后才能更好的理解中间件的开发模式。function applyMiddleware(...middlewares) {return createStore (...args) {const store createStore(...args);let dispatch () {throw new Error(Dispatching while constructing your middleware is not allowed. Other middleware would not be applied to this dispatch.);};const middlewareAPI {getState: store.getState,dispatch: (...args) dispatch(...args)};const chain middlewares.map(middleware middleware(middlewareAPI));dispatch compose(...chain)(store.dispatch);return { ...store, dispatch };};
}
1源码分析 接下来会分析函数中的代码为了便于理解在说明中还会给出相应的语句。 1利用剩余参数...middlewares的方式applyMiddleware()函数可以接收任意多个中间件。 2返回一个接收createStore参数的函数在函数体中调用Redux的createStore()函数得到一个store实例。const store createStore(...args);3middlewareAPI变量包含了中间件需要的参数即store.getState()和dispatch()方法。const middlewareAPI {getState: store.getState,dispatch: (...args) dispatch(...args)
};4将middlewareAPI变量传递给每个中间件并调用一次再将返回的函数组成一个新数组。const chain middlewares.map(middleware middleware(middlewareAPI));5通过compose()增强dispatch()方法compose()是Redux内置的函数可从右向左合成多个函数例如compose(f1, f2, f3)(arg)相当于f1(f2(f3(arg)))。dispatch compose(...chain)(store.dispatch);6最终得到一个对象包含store实例的方法和增强后的dispatch()方法。return { ...store, dispatch };
2使用方式 applyMiddleware()函数有两种使用方式下面用一个例子来演示先定义两个中间件m1和m2以及一个Reducer函数caculate()。const m1 store next action {console.log(m1);return next(action);
};
const m2 store next action {console.log(m2);return next(action);
};
function caculate(previousState {digit:0}, action) {let state Object.assign({}, previousState);switch (action.type) {case ADD:state.digit 1;break;case MINUS:state.digit - 1;}return state;
}1applyMiddleware()是一个三级柯里化的函数如果要使用那么可以像下面这样调用先传两个中间件再传createStore()函数最后传caculate()函数。let store applyMiddleware(m1, m2)(createStore)(caculate);2applyMiddleware()函数还可以作为createStore()的最后一个参数如下代码所示第一个参数是caculate()函数第二个参数是applyMiddleware()函数的结果。let store createStore(caculate, applyMiddleware(m1, m2));在applyMiddleware()函数的内部chain数组的值是[m1(next), m2(next)]由m1和m2返回的包含next参数的函数组成。增强后的dispatch()方法通过m1(m2(store.dispatch))得到具体如下所示。dispatch action {console.log(m1);return next(action);
};当调用store实例的dispatch()方法如下代码所示时会先输出“m1”然后调用next()函数也就是m2(next)输出“m2”最后调用m2中的next()函数也就是dispatch()方法。注意不能在中间件中直接调用dispatch()方法以免造成死循环。store.dispatch({ type: ADD });
三、redux-thunk 如果要在Redux中处理异步请求那么可以借助中间件实现目前市面上已有很多封装好的中间件可供使用例如redux-thunk、redux-promise或redux-saga等。本节将着重讲解redux-thunk中间件其核心代码如下所示。function createThunkMiddleware(extraArgument) {return ({ dispatch, getState }) next action {if (typeof action function) {return action(dispatch, getState, extraArgument);}return next(action);};
}首先检测action的类型如果是函数那么就直接调用并将dispatch、getState和extraArgument作为参数传入否则就调用next参数转移控制权。redux-thunk其实扩展了dispatch()方法使其参数既可以是JavaScript对象也可以是函数。 接下来用一个简单的例子演示redux-thunk的用法如下代码所示首先通过import引入redux-thunk并定义一个异步Action。import thunk from redux-thunk;
function asynAction() {return dispatch {fetch(server.php).then(response response.json(),error console.log(error)).then(data {dispatch(data); //{type: ADD}});};
}然后让asynAction()函数返回一个接收dispatch参数的函数在函数体内通过fetch()函数请求服务端的资源再利用得到的Promise处理获取到的数据。在第二个then()方法中data参数被赋为{type: ADD}也就是server.php响应的数据其代码如下所示。?php
$json [type ADD
];
echo json_encode($json);再接入redux-thunk中间件即将thunk传给applyMiddleware()函数最后发送一个异步Action如下所示。let store createStore(caculate, applyMiddleware(thunk));
store.dispatch(asynAction());