函数式编程+函数柯里化的使用方式: [juejin.cn/post/739210…]
上篇介绍了函数式编程的基本使用方式,但是组合函数的入参函数,均属于同步函数,碰到异步函数,又没法用了,于是产生了一个思考,如何整一个可以兼容异步函数的组合函数compose
compose函数实现(同步版)
function compose(...args){
return function(res){
return args.reduceRight((res,fn)=>{
return fn(res)
},res);
}
}
const getRes = compose(funB, funA);
const res = getRes(xxx);
先回忆同步的组合函数,给compose函数传入多个子函数去执行,会返回的是一个执行函数,执行函数接受一个入参,调用了会从右往左执行子函数,并且每个子函数的返回值,都会作为入参传递给到下一个子函数,直到所有子函数执行完毕;
compose函数实现(异步版)
说到异步,必然先想到Promise,按照同步版本的compose函数实现思路,最终结果应该会是从右往左依次把异步的结果,传递到下一个子函数的位置去执行
我们先来设想一下执行方式
const asyncCompose = () => {
return async (arg)=>{
const resA=await funcA(arg);
const resB=await funcB(resA);
const resC=await funcB(resB);
return resC
}
}
转换一下
const asyncCompose = () => async (arg)=>{
return await funcC(await funcB(await funcA(arg)));
}
传递执行结果,那自然是用上reduce和reduceRight
最终版:
const asyncCompose = (...funcs) =>
funcs.reduceRight((prePromise, curPromise) => {
return async (...args) => curPromise(await prePromise(...args))
});
使用demo
const funcA = (message) => new Promise((resolve, reject) => {
setTimeout(() => resolve(message + " A"), 1000);}
);
const funcB = (message) => new Promise((resolve, reject) => resolve(message+' B'));
const funcC = (message) => Promise.resolve(message + " C");
const funcD = (message) => message + " D" ;
const fnabcd = asyncCompose(funcD, funcC, funcB, funcA);
fnabcd("举个栗子").then(res=>{
console.log('log=>res',res);//log=>res 举个栗子 A B C D
})
.catch(e=>{
console.log('log=>错误',e);
})
错误捕获
- 我们把funcB的
resolve(message+' B')改成reject(message+' B'),执行到funcB,后面因为进入catch了,不会继续往后执行
const funcA = (message) => new Promise((resolve, reject) => {
setTimeout(() => resolve(message + " A"), 1000);}
);
const funcB = (message) => new Promise((resolve, reject) => {
console.log(message);//举个栗子 A, 是funcA返回的promise的fulfill的结果
reject(message+' B')
});
const funcC = (message) => Promise.resolve(message + " C");
const funcD = (message) => message + " D" ;
const fnabcd = asyncCompose(funcD, funcC, funcB, funcA);
fnabcd("举个栗子").then(res=>{
console.log('log=>res',res);
})
.catch(e=>{
console.log('log=>错误',e);//log=>错误 funcBB-error
})
- 我们改一下
funcD,增加一些执行会异常代码
const funcA = (message) => new Promise((resolve, reject) => {
setTimeout(() => resolve(message + " A"), 1000);}
);
const funcB = (message) => new Promise((resolve, reject) => resolve(message+' B'));
const funcC = (message) => Promise.resolve(message + " C");
const funcD = (message) => message + " D" + a;
const fnabcd = asyncCompose(funcD, funcC, funcB, funcA);
fnabcd("举个栗子").then(res=>{
console.log('log=>res',res);
})
.catch(e=>{
console.log('log=>错误',e);//log=>错误 ReferenceError: a is not defined
})
至此,asyncCompose完成,兼容了同步和异步函数