可以将此功能重写为Ramda管道吗?怎么样?

时间:2018-03-14 21:39:07

标签: javascript functional-programming ramda.js

我想知道是否可以将A重写为D CC而不将D的结果传递给const A = async payload => { const resultB = await B(payload); const resultC = await C(resultB); const resultD = await D(resultB); return resultB; }; 的Ramda管道}:

const R = require('ramda');

const then = R.curry((f, p) => p.then(f));

const trace = R.curry(async(name, data) => `${name}(${data})`);

const B = trace('B');
const C = trace('C');
const D = trace('D');

const A = async payload => {
    const resultB = await B(payload);
    await C(resultB);
    await D(resultB);
    return resultB;
   };

const A_Pipe = R.pipe (B, then(C), then(D));

A('x').then(console.log); // -> B(x)

A_Pipe('x').then(console.log); // -> D(C(B(x)))

编辑:这似乎没有产生预期的结果:

attrs

2 个答案:

答案 0 :(得分:4)

显然Ramda plans to add R.then但看起来他们还没有找到它

在此之前,您可以自己制作

const then = 
  R.curry((f, p) => p.then(f))

const A =
  R.pipe(B, then(C), then(D))

这是一个完整的程序,您可以在Ramda REPL

中粘贴
const then = f => p =>
  p.then (f)

const effect = f => x =>
  (f (x), x)

const trace =
  effect (console.log)

const fakeFetch = x =>
  new Promise (r => setTimeout (r, 200, x))

const B = x =>
  fakeFetch (trace (`[B: ${x}]`))

const C = x =>
  fakeFetch (trace (`[C: ${x}]`))

const D = x =>
  fakeFetch (trace (`[D: ${x}]`))

const A =
  pipe (B, then (C), then (D))

A (1)
// => { Promise "[D: [C: [B: 1]]]" }

输出

[B: 1]
[C: [B: 1]]
[D: [C: [B: 1]]]

我看到你在那里做了什么

仔细检查后,CD是副作用函数,其返回值将被丢弃 - resultCresultD未使用。相反,resultB是你似乎关心的唯一价值

const A = async payload => {
  const resultB = await B(payload)
  const resultC = await C(resultB)
  const resultD = await D(resultB)
  return resultB
}

使用R.composeR.pipe编写函数时,将返回值1传递给下一个函数。但是,在您的情况下,CD不应影响输入。我引入asyncTap来编码您的意图 - 与上面的R.tapeffect进行比较

const asyncTap = f => p =>
  p.then (R.tap (f))

const A =
  pipe (B, asyncTap (C), asyncTap (D))

A (1) .then (console.log, console.error)
// => { Promise "[B: 1]" }

输出 - 请参阅Ramda REPL

中的完整程序
[B: 1]
[C: [B: 1]]
[D: [B: 1]]
[B: 1]

这引出了一个问题:您使用resultCresultD做了哪些 ?函数式编程是关于使用纯粹的无副作用函数编写程序。如果您在以功能方式表达自己的程序时遇到困难,有时可能表明您没有以功能性方式思考。

答案 1 :(得分:0)

不是ramda,但是它可以满足您的要求。

const { pipe, tap } = require('rubico')

const A = pipe([
  B,
  tap(C),
  tap(D),
])
相关问题