node compose函数式组合

234 阅读2分钟

理解什么是函数组合

1.无组合状态

//1.无组合状态
async function fn1(next){
    console.log('fn1')
    console.log('end fn1')
}

async function fn2(next){
    console.log('fn2')
    console.log('end fn2')
}

function fn3(next){
    console.log('fn3')
}

fn1(fn2(fn3())) 

// 结果
// fn3
// fn2
// end fn2
// fn1
// end fn1

2.两个函数的组合

// 2.两个函数的组合,这里特点是参数是一个方法的声明
// 没有使用()立刻执行fn()。留给函数内部执行next()
async function fn1(next){
    console.log('fn1')
    next && await next()
    console.log('end fn1')
}
//这里的fn2 的参数next 其实可以忽略没有用到。
async function fn2(next){
    console.log('fn2')
    next && await next()
    console.log('end fn2')
}

fn1(fn2)
// 结果
// fn1
// fn2
// end fn2
// end fn1

3.3个或以上组合状态


//3 多个函数的组合,
// 由于参数都需要是声明,而不是立即调用,
// 所以参数都要包裹成声明方式 () => {}
// 除了最后一个,因为最后一个就是定义不用再嵌套调用 ()
async function fn1(next){
    console.log('fn1')
    next && await next()
    console.log('end fn1')
}

async function fn2(next){
    console.log('fn2')
    next && await next()
    console.log('end fn2')
}
async function fn3(next){
    console.log('fn3')
    next && await next()
    console.log('fn3')
}

async function fn4(next){
    console.log('fn4')
    next && await next()
    console.log('fn4')
}


fn1(() => fn2(() => fn3(fn4)))

// 结果
// fn1
// fn2
// fn3
// fn4
// fn4
// fn3
// end fn2
// end fn1

实战


const add = (x,y) =>  x + y
const square = (x) => x * x
//方法1 直接嵌套
const res = square( add(1,2))
console.log(res)

//方法2 固定两个函数嵌套动态嵌套
const compose = (fn1,fn2) => {
    return (...args) => {
       return fn2(fn1(...args))
    }
}

const composeFn = compose(add,square)
console.log(composeFn(1,2))

//方法3 数组嵌套
//通过...[first,...other] 把数组解构成  能索引第一个和后面新数组的结构
const composeMore = (...[first,...other]) => (...args) => {
    let ret = first(...args)//第一个方法先执行一遍
    other.forEach( (fn) => {//按顺序从第二个开始执行方法
        ret = fn(ret)//传入参数是全局的上一次结果
    })
    return ret;
}
const composeMoreFn = composeMore(add,square)
console.log(composeMoreFn(1,2))

//方法4 支持next()方法动态嵌套
function composePromise(middlewares) {
    console.log("composePromise")
    return function () {//这里定义方法形式,而不是立刻执行,留给业务代码执行
        return dispatch(0);//从第一个方法开始执行
        function dispatch(i) { //结果一定返回一个promies 成功对象
            let fn = middlewares[i];
            console.log("i",i,fn)
            if(!fn){//处理 下面代码dispatch(i + 1) 最后一个是多+1 ,不存在的fn的情况,一样要返回promise对象
                return Promise.resolve(); //对应的执行代码为: await next()方法
            }
            return Promise.resolve(  
                fn( function next() {//这里定义方法形式,而不是立刻执行,留给业务代码执行
                    return dispatch(i + 1)//传入下一个数组对象的方法,并返回Promise对象
                })
            )
        }
    }
}
//测试代码

async function fn1(next){
    console.log('fn1')
    await next()
    console.log('end fn1')
}

async function fn2(next){
    console.log('fn2')
    await delay()
    await next()
    console.log('end fn2')
}

function fn3(next){
    console.log('fn3')
}

function delay(){
    return Promise.resolve(res => {
        setTimeout(() => reslove(),2000)
    })
}

const middlewares = [fn1,fn2,fn3]
const finalFn = composePromise(middlewares)
finalFn()