redux 中间件 级联

136 阅读2分钟
  • 多个中间件级联,就像是套娃一样,从外道里面套,执行的时候是从里面到外面执行
  • 多个中间件级联,就像是套娃一样,从外道里面套,321 ||compose(add3, add2, add1)
  • 执行的时候是从里面到外面执行顺序是,最里面的先执行 123

function add1(str) {
    return '1 '+ str;
}
function add2(str) {
    return '2' + str;
}
function add3(str) {
    return '3' + str;
}
/* function compose(...funcs) {
    return function (args) {
        for (let i = funcs.length - 1; i >= 0; i--) {
            args = funcs[i](args);
        }
        return args;
    }
} */
function compose(...funcs) {
    if (funcs.length == 0)
        return args => args;
    if (funcs.length === 1) {
        return funcs[0];
    }
    return funcs.reduce((a, b) => (...args) => a(b(...args)));
}
/**
 * funcs=[add3, add2, add1]
 * 第一次执行 a=add3,b=add2 返回 (...args) => add3(add2(...args))
 * 第二次执行 a=(...args) => add3(add2(...args)),b=add1 返回 (...args)=>add3(add2(add1(...args))))
 * 最终的返回值就是 (...args)=>add3(add2(add1(...args))))
 */

let fn = compose(add3, add2, add1);
let result = fn('dis');//321 dis
function compose(...funcs) {
    if (funcs.length === 0) {
        return args => args;
    }
    if (funcs.length === 1) {
        return funcs[0];
    }
    /*    return function (args) {
        for (let i = funcs.length - 1; i >= 0; i--) {
            args = funcs[i](args);
        }
        return args;
    }*/
    return funcs.reduce((a, b) => (...args) => a(b(...args)));
}
export default compose;

promise

function promise({ getState, dispatch }) {
    return function (next) {
        return function (action) {//成为我们改造后的dispatch方法
            if (action.then && typeof action.then === 'function') {
                return action.then(dispatch);
            } else if (action.payload && action.payload.then && typeof action.payload.then === 'function') {
                action.payload
                    .then(payload => dispatch({ ...action, payload }))//{type:'add1',payload:.8}
                    .catch(error => {//error .3
                        //在reducer里可以通过action里有没有error:true属性来判断是成功还是失败了
                        dispatch({ ...action, payload: error, error: true });
                        return Promise.reject(error);
                    })
            } else {
                next(action);
            }
        }
    }
}
export default promise;

thunk

function thunk({ getState, dispatch }) {
    return function (next) {
        return function (action) {//成为我们改造后的dispatch方法
            if (typeof action === 'function') {
                //执行此函数,并且传入dispatch和getState
                return action(dispatch, getState);
            }
            //执行原始的store.dispatch方法
            return next(action);
        }
    }
}
export default thunk;

中间件级联原理


let logger1 = next => action => {
    // 执行
    // 这是接收的
    console.log(action);
    console.log('logger1');
    /* action => {
    //action => {
    //     console.log('logger3');
    //     //  dispatch() { console.log('原生的dispatch'); }
    //     next(action);
    // }
}*/
    //logger2
    next(action);
}
let logger2 = next => action => {
    //action => {
    //     console.log('logger3');
    //     //  dispatch() { console.log('原生的dispatch'); }
    //     next(action);
    // }
    console.log(action);
    console.log('logger2');
    //logger3
    next(action);
}
//next/ dispatch() { console.log('原生的dispatch'); }
let logger3 = next => action => {
    console.log(action);

    console.log('logger3');
    //  dispatch(action) { console.log('原生的dispatch'); }
    //next 就是dispatch(action) { console.log('原生的dispatch'); }
    next(action);
}
let store = { dispatch() { console.log('原生的dispatch'); } };
//let composed = compose(logger1, logger2, logger3);
function composed(oldDispatch) {
    let logger3Next = logger3(oldDispatch);
    let logger2Next = logger2(logger3Next);
    let newDispatch = logger1(logger2Next);
    return newDispatch;
}

let newDispatch = composed(store.dispatch);

newDispatch({ type: "ADD" });