JavaScript中的函数编排

86 阅读1分钟

一、函数编排的使用场景

前端通常会有对原数据进行加工处理的情况,如果多次的数据处理都放在一个函数中就会变的很臃肿难以维护:

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;
        },
      ]);
    }

三、总结

函数编排 通过可插拔的方式控制函数按指定顺序执行