繁体   English   中英

这个函数可以重写为 Ramda 管道吗? 如何?

[英]Can this function be rewritten as a Ramda pipe? How?

我想知道是否可以将A重写为 Ramda 管道,其中D等待C而无需将C的结果传递给D

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

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

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)))

显然Ramda 计划添加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组合函数时,一个函数的返回值会传递给下一个函数。 但是,在您的情况下, CD不应影响输入。 我引入asyncTap来编码你的意图——与R.tap或上面的effect进行比较

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做什么? 函数式编程是关于用纯粹的、无副作用的函数编写程序。 当您难以以函数式方式表达您的程序时,有时可能表明您没有以函数式方式思考。


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

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

const A = pipe([
  B,
  tap(C),
  tap(D),
])

暂无
暂无

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

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