JS实现唱跳rap篮球流水线的方式

59 阅读1分钟

先让我们想一个业务模型吧,身为一名ikun,我们想成为一名合格的偶像练习生,需要会唱跳rap篮球,缺一不可,业务模型来点有创意的话,唱=》跳=》rap=》篮球=》成为练习生,如果不会'跳',那么流程就不往下执行了。

首先,先来最low的写法:

    import * as _ from 'lodash';
    const skill: Array<string> = ['sing', 'dance', 'rap', 'basketball'];
    const find = (arr: string[], str: string) => {
      return _.find(arr, (v: string): boolean => {
        if (v === str) {
          return true;
        } else {
          return false;
        }
      });
    };
    const allSuccessStr = `I'm kunkun`;
    const successStr = (str: string) => `i can ${str}`;
    const failStr = (str: string) =>
      `I'm not an idol trainee, because i can not ${str}`;
      if (find(skill, 'sing')) {
      console.log(successStr('sing'));
      if (find(skill, 'dance')) {
        console.log(successStr('dance'));
        if (find(skill, 'rap')) {
          console.log(successStr('rap'));
          if (find(skill, 'basketball')) {
            console.log(successStr('basketball'));
            console.log(allSuccessStr);
          } else {
            console.log(failStr('basketball'));
          }
        } else {
          console.log(failStr('rap'));
        }
      } else {
        console.log(failStr('dance'));
      }
    } else {
      console.log(failStr('sing'));
    }

可以看到,嵌套特别特别多,代码实在是过于臃肿,可读性特别差,我们要把嵌套扁平化,(在很深的树形结构,也可以讲结构扁平化,这样效率会成倍增加)

其次,这是普通的写法:

    if (skill['sing']) {
      console.log(successStr('sing'));
    } else {
      console.log(failStr('sing'));
      return;
    }
    if (skill['dance1']) {
      console.log(successStr('dance'));
    } else {
      console.log(failStr('dance'));
      return;
    }
    if (skill['rap']) {
      console.log(successStr('rap'));
    } else {
      console.log(failStr('rap'));
      return;
    }
    if (skill['basketball']) {
      console.log(successStr('basketball'));
    } else {
      console.log(failStr('basketball'));
      return;
    }

之后,这是再次优化的最佳写法,我们把数组改为对象,这样时间复杂度就是1了:

interface Skill {
  sing: boolean;
  dance: boolean;
  rap: boolean;
  basketball: boolean;
  [propName: string]: boolean;
}
 const allSuccessStr = () => console.log(`I'm kunkun`);
    const successStr = (str: string) => `i can ${str}`;
    const failStr = (str: string) =>
      `I'm not an idol trainee, because i can not ${str}`;
    const skill: Skill = {
      sing: true,
      dance: true,
      rap: true,
      basketball: true,
    };
    const isSkill = (v: string): Boolean => {
      if (skill[v]) {
        successStr(v);
        return true;
      } else {
        failStr(v);
        return false;
      }
    };
    isSkill('sing') &&
      isSkill('dance') &&
      isSkill('rap') &&
      isSkill('basketball') &&
      allSuccessStr();

最后,放大招,Rxjs直接秒杀!

    interface Skill {
      sing: boolean;
      dance: boolean;
      rap: boolean;
      basketball: boolean;
      [propName: string]: boolean;
    }
   const skill: Skill = {
      sing: true,
      dance: true,
      rap: true,
      basketball: true,
    };
    const source = of('sing', 'dance', 'rap', 'basketball')
      .pipe(takeWhile((v) => skill[v] == true))
      .subscribe(
        (val) => console.log(val),
        () => {},
        () => console.log('done')
      );