一、函数编排的使用场景
前端通常会有对原数据进行加工处理的情况,如果多次的数据处理都放在一个函数中就会变的很臃肿难以维护:
function resolveHtmlData(htmlStr) {
// replace img src
//replaceLink
// removeUnusedTag
...
return htmlStr;
}
对上面的代码进行优化,将不同的逻辑封装到函数中函数中进行隔离
function resolveHtmlData(htmlStr){
// replace img src
function replaceImageSrc(){...}
function replaceLink(){...}
function removeUnusedTag(){...}
...
return replaceImageSrc(replaceLink(removeUnusedTag(htmlStr)));
}
上面的代码产生了replaceImageSrc(replaceLink(removeUnusedTag(htmlStr)))这样的compose嵌套,看起来不够优雅,于是我们的终极大招函数编排出现了。
二、函数编排的实现
2.1 基础版
函数编排通常是基于循环实现,因此可以巧妙利用reduce实现函数编排。
function compose(data, fns){
return fns.reduce((pre, next)=>next(pre), data);
}
const total = compose(1, [
(x)=>x+1,
(x)=>x-2,
(x)=>x*3,
(x)=>x-4,
(x)=>x/5,
]);
2.2 异步函数编排
现在问题又来了,函数编排的过程中可能涉及异步操作,比如接口调用等,普通的函数编排还是不够用,还得支持异步函数编排
function compose(data, fns) {
return fns.reduce(async (pre, next) => next(await pre), data);
}
const request = new Promise((resolve, reject) => setTimeout(() => {
resolve();
}, 300));
async function foo() {
const total = await compose(1, [
async (x) => {
await request;
return x + 1;
},
async (x) => x - 2,
async (x) => x * 3,
async (x) => x - 4,
async (x) => {
await request;
return x / 5;
},
]);
}
三、总结
函数编排 通过可插拔的方式控制函数按指定顺序执行。