编程里 pipe 与 compose 有什么区别

一直人的疑问,chatGPT 给出答案
更新于: 2023-06-28 08:43:42

结论

  • 管道和组合都是函数组合的技术,它们的主要区别在于函数的组合顺序
  • pipe 管道按照函数的顺序组合
  • compose 而组合按照相反的顺序组合

实际使用

  • pipe.sync(默认是这个)
  • pipe.async
yarn add @jswork/pipe

共同点

在编程中,"pipe"和"compose"是两种常见的函数组合技术。

1. Pipe(管道):管道是一种将多个函数组合在一起的技术,其中每个函数的输出作为下一个函数的输入。通过管道,您可以按照特定的顺序依次将函数应用于数据。这种方式使代码易于阅读和理解,因为数据的处理流程按照函数的顺序进行。

  示例代码(使用JavaScript):  

const pipe = (...functions) => (input) =>
    functions.reduce((output, func) => func(output), input);

  const add = (x) => (y) => x + y;
  const multiply = (x) => (y) => x * y;
  const subtract = (x) => (y) => x - y;

  const calculate = pipe(
    add(5),
    multiply(2),
    subtract(10)
  );

  const result = calculate(3); // 结果为 (3 + 5) * 2 - 10 = 6

  在上面的例子中,通过使用`pipe`函数,我们可以将`add`、`multiply`和`subtract`函数按照顺序组合起来,然后将数据(3)传递给这个组合函数。结果是将数据依次传递给每个函数,并返回最终结果。

2. Compose(组合):组合是另一种函数组合技术,其中函数按照相反的顺序组合。也就是说,每个函数的输出作为前一个函数的输入。与管道不同,组合的顺序是从右到左的。

  示例代码(使用JavaScript):

const compose = (...functions) => (input) =>
    functions.reduceRight((output, func) => func(output), input);

  const add = (x) => (y) => x + y;
  const multiply = (x) => (y) => x * y;
  const subtract = (x) => (y) => x - y;

  const calculate = compose(
    subtract(10),
    multiply(2),
    add(5)
  );

  const result = calculate(3); // 结果为 (3 + 5) * 2 - 10 = 6

 在上面的例子中,通过使用`compose`函数,我们将`subtract`、`multiply`和`add`函数按照相反的顺序组合起来。数据(3)首先传递给最右边的函数,然后输出作为下一个函数的输入,以此类推,直到达到最左边的函数,并返回最终结果。

综上所述,管道和组合都是函数组合的技术,它们的主要区别在于函数的组合顺序。管道按照函数的顺序组合,而组合按照相反的顺序组合。选择使用哪种技术取决于您对数据处理流程的理解和设计需求。

实际代码

pipe,正向

考虑异常,并对应地方给出 warning

不影响正常结果返回

// 原始版本
const pipe =
  (...functions) =>
  (input) =>
    functions.reduce((acc, func) => func(acc), input);

// 改进版本
const pipe2 =
  (...functions) =>
  (input) =>
    functions.reduce((acc, func) => {
      try {
        return func(acc);
      } catch (error) {
        console.log(error);
        console.warn("Function execution warning:");
        return acc;
      }
    }, input);

const addOne = (n) => n + 1;
const double = (n) => n * 2;
const sqrt = (n) => {
  if (n < 0) {
    throw new Error("Square root of negative number is undefined.");
    return n;
  }
  return Math.sqrt(n);
};

const result = pipe2(addOne, double, sqrt)(-2);
console.log(result);