先看一张图:
我们在react中使用redux时有时候需要使用redux的中间件,那么redux的中间件是如何是实现的呢?看代码:
代码语言:javascript复制let store = {
dispatch(action) {
console.log(action);
}
}
let fn1 = function (store) {
return function (next) {
console.log("fn1 next start")
return function (action) {
console.log("fn1 start")
let result = next(action)
console.log("fn1 end")
return result;
}
}
}
let fn2 = function (store) {
return function (next) {
console.log("fn2 next start")
return function (action) {
console.log("fn2 start")
let result = next(action)
console.log("fn2 end")
return result;
}
}
}
let fn3 = function (store) {
return function (next) {
console.log("fn3 next start")
return function (action) {
console.log("fn3 start")
let result = next(action)
console.log("fn3 end")
return result;
}
}
}
let arrs = [fn1, fn2, fn3];
function applymid(store, arrs){
let dispatch = store.dispatch;
arrs.forEach(element => {
dispatch= element(store)(dispatch)
});
return Object.assign({},store,{dispatch});
}
// 循环过程中 第一次执行element(store)(dispatch);得到的结果是
dispatch1 = function (action) {
console.log("fn1 start")
let result = next(action) //此处next为原始最初的dispatch
console.log("fn1 end")
return result;
}
// 循环第二次执行element(store)(dispatch);得到的结果是:
dispatch2 = function (action) {
console.log("fn2 start")
let result = next(action) //此处next为原始最初的dispatch1
console.log("fn2 end")
return result;
}
// 此时的next就是上一次的dispatch 即dispatch1代入得到:
dispatch = function (action) {
console.log("fn2 start")
let result = (function (action) {
console.log("fn1 start")
let result = next(action) //此处next为原始最初的dispatch
console.log("fn1 end")
return result;
})(action);
console.log("fn2 end")
return result;
}
// 简化:
dispatch = function (action) {
console.log("fn2 start")
console.log("fn1 start")
let result = next(action) //此处next为原始最初的dispatch
console.log("fn1 end")
console.log("fn2 end")
}
let s = applymid(store,arrs);
s.dispatch(999);
首先我们要用一句话来概括redux中间件的原理,那就是store要执行dispatch时,要按照中间件的顺序执行中间件,最后再执行dispatch,逻辑图就像一个洋葱。
如何实现呢?这里面遵循几条原则,首先中间件的定义方式,一个中间件涉及三个函数,a函数返回b函数,b函数返回c函数,中间件函数本质可以连续调用执行 中间件函数(store)(next)(action)。
中间件函数连续调用两次返回的函数就是新版的dispatch,即dispatch = 中间件函数(store)(next);
dispatch = 中间件函数(store)(dispatch);是中间状态,一开始的dispatch等于store.dispatch,也是最原始的dispatch,代码中多次执行dispatch = 中间件函数(store)(dispatch),多次对dispatch进行包装并对dispatch进行赋值,等号右侧对dispatch进行包装,后者说是修饰,类似修饰符,修饰完成后重新赋值个dispatch,这样dispatch就是更新完的dispatch了。
applyMiddleware的本质就两点,遍历中间件,用中间件修饰dispatch,重新给dispatch赋值,遍历完成后得到新的dispatch返回新的dispatch。
这种代码结构比较有意思,需要反复揣摩才能熟练掌握,希望对你有所帮助。