简体   繁体   English

你能帮我理解 javascript 中的管道功能是如何工作的吗?

[英]Can you help me understand how piping functions in javascript work?

I am reading a book called Learning React, 2nd Edition .我正在读一本名为Learning React, 2nd Edition的书。 There's a section about function composition under functional programming section.在函数式编程部分下有一个关于 function 组合的部分。 The code snippet and explanation provided are not super clear to me.提供的代码片段和解释对我来说不是很清楚。 Here's the code snippet from the book -这是书中的代码片段 - 在此处输入图像描述 在此处输入图像描述

Here's the above code in code snippet -这是代码片段中的上述代码 -

const both = compose(
  civilianHours,
  appendAMPM
):

both(new Date());

const compose = (...fns) => arg => 
  fns.reduce((compose, f) => f(composed), arg);

I don't understand what the author is trying to explain here.我不明白作者想在这里解释什么。 Here's the explanation provided from the book for this snippet.这是书中为这个片段提供的解释。

The compose function is a higher-order function. It takes functions as arguments and returns a single value. compose function 是一个高阶的 function。它接受函数 arguments 并返回一个值。 compose takes in functions as arguments and returns a single function. In this implementation, the spread operator is used to turn those function arguments into an array called fns. compose 接受函数作为 arguments 并返回单个 function。在此实现中,展开运算符用于将这些 function arguments 转换为称为 fns 的数组。 A function is then returned that expects one argument, arg.然后返回一个 function,它需要一个参数 arg。 When this function is invoked, the fns array is piped starting with the argument we want to send through the function. The argument becomes the initial value for compose, then each iteration of the reduced callback returns.当这个 function 被调用时,fns 数组以我们要通过 function 发送的参数开始进行管道传输。该参数成为 compose 的初始值,然后减少回调的每次迭代返回。 Notice that the callback takes two arguments: composed and a function f.请注意,回调采用两个 arguments: composed 和一个 function f。 Each function is invoked with compose, which is the result of the previous function's output. Eventually, the last function will be invoked and the last result returned.每一个function都是用compose调用的,就是前面这个函数的output的结果,最终会调用最后一个function,返回最后一个结果。

So can anyone explain to me how function piping works in javascript with some examples?那么谁能用一些例子向我解释 function 管道在 javascript 中是如何工作的? It would be nice if someone could explain the above code snippet too.如果有人也可以解释上面的代码片段,那就太好了。 Especially what the arg is doing sitting over there.尤其是arg坐在那边正在做什么。

Here's another code snippet for the same question -这是同一问题的另一个代码片段 -

const add2 = (x) => x + 2;
const subtract1 = (x) => x - 1;
const multiplyBy5 = (x) => x * 5;

const pipe = (...fns) => (val) => fns.reduce((prev, fn) => fn(prev), val);

const pipeResult = pipe(add2, subtract1, multiplyBy5)(5);

console.log(pipeResult); // = 30

It might be clearer if we use a loop rather than reduce ( reduce can be hard to read), and use the verbose form of the arrow function rather than the concise one:如果我们使用循环而不是reducereduce可能难以阅读)并使用箭头 function 的详细形式而不是简洁的形式,可能会更清楚:

const compose = (...fns) => {
    return (arg) => {
        let composed = arg;
        for (const fn of fns) {
            composed = fn(composed);
        }
        return composed;
    };
};

compose accepts a bunch of functions as discrete arguments, gathering them all up into an array with a rest parameter ( ...fns ). compose接受一组离散的 arguments 函数,将它们全部收集到一个带有 rest 参数 ( ...fns fns ) 的数组中。 It returns a function that accepts a single parameter ( arg ).它返回一个接受单个参数 ( arg ) 的 function。 When you call that function, it loops through the functions in fns .当您调用 function 时,它会循环遍历fns中的函数。 The first function gets arg (which I've copied to composed above).第一个 function 获取arg (我已将其复制到上面的composed中)。 The code takes the result of calling the first function to give to the next, then keeps the result of calling that to call the next, etc., eventually returning the last result when it runs out of functions.该代码将调用第一个 function 的结果传递给下一个,然后保留调用该结果以调用下一个,等等,最终在函数用完时返回上一个结果。

In the both example, it's basically doing this:在这both例子中,它基本上是这样做的:

let firstResult = civilianHours(new Date());
let composed = appendAMPM(firstResult);
// Or
let composed = appendAMPM(civilianHours(new Date()));

(except oddly the book's example doesn't use the return value of both .) (奇怪的是,这本书的例子没有使用both的返回值。)

The "pipeline" concept comes from the fact that compose is basically laying out the functions it receives in a row, where each function passes its result to the next function, like a series of connected pipes that a liquid flows through: “管道”的概念来自这样一个事实,即compose基本上是将它接收到的函数排成一行,其中每个 function 将其结果传递给下一个 function,就像液体流过的一系列连接的管道:

arg −−−> add2 −−−> subtract1 −−−> multiplyBy5 −−−> result

Here's a live example of the math example at the end of the question, with some logging to help show what's going on:这是问题末尾的数学示例的一个实时示例,其中包含一些日志记录以帮助显示正在发生的事情:

 const compose = (...fns) => { console.log(`Creating function to do ${fns.map(fn => fn.name).join(" => ")}`); return (arg) => { let composed = arg; for (const fn of fns) { const msg = `${fn.name}(${composed})`; composed = fn(composed); console.log(`${msg} returns ${composed}`); } return composed; }; }; const add2 = (x) => x + 2; const subtract1 = (x) => x - 1; const multiplyBy5 = (x) => x * 5; const pipeResult = compose(add2, subtract1, multiplyBy5)(5); console.log(pipeResult); // = 30

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM