vuex中间件
通过store.subscribe注入到vuex中,通过_subscriber数组收集起来,在内置函数commit的时候就遍历执行那些数组里面的函数
redux中间件
通过不断包装store.dispatch,来实现组合调用。一个高阶函数接受旧的dispatch,内部函数接受action,执行完副作用后在调用旧的dispatch(action)。
通过数组的reduce,不断包装函数,然后通过传递dispatch来完成组合。最后组成的新的store.dispatch会替代原本的store.dispatch,数组第一个的store.dispatch会先被执行
function logDispatch(dispatch) {
return function(action) {
console.log('dispatch')
dispatch(action)
}
}
function errorDispatch(dispatch) {
return function(action) {
try{
dispatch(action)
}catch(e){
console.log(e)
}
}
}
function customDispatch(dispatch) {
return function(action) {
console.log('custom')
dispatch(action)
}
}
const wrapperDisapatch = [logDispatch, errorDispatch, customDispatch].reduce(
(wrapperDispatch,dispatch) => {
return (...args) => wrapperDispatch(dispatch(...args))
})
store.dispatch = wrapperDisapatch(store.dispatch)
store.dispacth({
type: '',
payload: ''
})
koa中间件
通过遍历插件,控制index的位置来访问下一个数组元素,然后调用next。就能跳转到下一个插件的位置,官方的next没有接收参数,其实可以接收参数。
下面利用上面那种中间件来实现功能:
vuex只是单纯的遍历还是next与next之间没有递进关系,没有办法中途终止dispatch
// redux
// function filterString(next) {
// return function (file) {
// console.log(file)
// return typeof file === 'string'? next(file + '1') : file
// }
// }
// function filterEnd(next) {
// return function (file) {
// console.log(file)
// return /1/.exec(file)? next(file+'2') : file
// }
// }
// function addEnd(next) {
// return function (file) {
// console.log(file)
// next(file + '#EXT-X-ENDLIST' + '\n')
// }
// }
// function setData(next) {
// return function(file) {
// console.log(file)
// }
// }
// ([filterString, filterEnd, addEnd].reduce((pre, next) => {
// return (...args)=> pre(next(...args))
// }))(setData)('bbb')
// koa
function filterString(file, next) {
console.log('filter', file)
return typeof file === 'string'? next(file + '1') : file
}
function filterEnd(file, next) {
console.log('filterEnd', file)
return /1/.exec(file)? next(file+'2') : file
}
function addEnd(file,next) {
console.log('addEnd', file)
next(file + '#EXT-X-ENDLIST' + '\n')
}
function setData(file,next) {
console.log('data', file)
}
function compose(arr) {
let index = -1
return function (file) {
// i下个next的位置
function dispatch(i, ...args) {
if(i <= index) {
throw('more next')
}
index = i
const fn = arr[index]
if(!fn) return;
return fn(...args, dispatch.bind(null, i + 1))
}
return dispatch(0, file)
}
}
compose([filterString, filterEnd, addEnd, setData])('bbb')