javascript Pipe方法执行流

发布时间 2023-12-20 10:04:38作者: 乌拉小考

pipe的概念很简单,就是将n个函数组合起来,他是一个从左到右的流,每个函数执行的时候都传入之前函数的结果。下面写一个返回一个人名字的函数:

getName = (person) => person.name;
getName({name: "Buckethead"})
// 返回 "Buckethead"

接下来写一个将字符串大写的函数

uppercase = (string) => string.toUpperCase();
uppercasse("Buckethead")
// 返回 "BUCKETHEAD"

所以为了获取大写的名字,接下来这样写:

name = getName({name: "Buckethead"})
uppercase(name);
// 返回 "BUCKETHEAD"

如果去掉name参数,就变成:

uppercase(getName({ name: 'Buckethead' }));

这样看起来还行,但是这样变得拥挤了,如果我们再加一个函数来获取字符串的前6个字符呢?,那么使用一个函数:

get6Characters = (string) => string.substring(0, 6);

get6Characters('Buckethead');
// 'Bucket'

将上面的函数组合再一起变成了:

get6Characters(uppercase(getName({ name: 'Buckethead' })));

// 'BUCKET';

那么如果再加一个反转字符串的函数:

reverse = (string) =>
string
  .split("")
  .reverse()
  .join("")

reverse("Buckethead")
// 'daehtekcuB'

这样的话就变成了:

reverse(get6Characters(uppercase(getName({ name: 'Buckethead' }))));
// 'TEKCUB'

接下来我们使用pipe进行拯救上面这一串函数调用。为了不创建一连串的中间参数,让我们将这一串函数pipe起来

pipe(
  getName,
  uppercase,
  get6Characters,
  reverse
  )({name: "Buckethead"})

看起来想todo列表。
接下来一步步解析pipe做了什么,作为demo,将使用Eric Elliott’s functional programming articles.的继承。

pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x)

使用...参数,可以pipe很多个函数,每个函数接收前一个函数的返回和他的所有reduced到一个值里面。就像下面这样:

pipe(
  getName,
  uppercase,
  get6Characters,
  reverse  
)({name: "Buckethead"})
// 'TEKCUB'

接下来展开pipe并且debugger这些表达式,一步一步的来看:

pipe = (...functions) => (value) => {
  debugger;

  return functions.reduce((currrentValue, currentFunction) => {
    debugger;
    return currentFunction(currentValue);
}, value);
}


使用示例中的方法来pipe,并且展开看参数:

检查本地变量。有4个函数参数,并且参数值是{name: "Buckethead"}。因为使用了变量参数,pipe允许很多的函数作为参数使用并且会一个个循环调用他们。

接下来的debugger中,将深入到reduce,currentValue将传递给currentFunction并且返回。
我们看到结果是Buckethead,因为当前函数currentFunction 是返回name函数,接下来这个函数会被返回并且去掉,意味着name
变成了一个新的currentValue,接下来继续debugger。


现在currentValue Buckethead因为这是再上一个函数中我们得到的返回。当前的currentFunctionuppercase,所以我们的到了BUCKETHEAD作为currentValue

同样的,获取BUCKETHEAD的前面6个字符串并且把他们交给下一个函数。

接下来调用反转字符的方法reverse

以上就是pipe执行的流程,总的来说就是将一串函数作为参数传入pipe方法里面,然后传递一个参数进去,然后pipe会将所有的参数函数依次执行,将上一步的返回结果传入到下一步之中。