[英]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]]]
我看到你在那里做了什么
仔细检查后, C
和D
是副作用函数,它们的返回值被丢弃——没有使用resultC
和resultD
。 相反, resultB
是您似乎唯一关心的值
const A = async payload => {
const resultB = await B(payload)
const resultC = await C(resultB)
const resultD = await D(resultB)
return resultB
}
当使用R.compose
或R.pipe
组合函数时,一个函数的返回值会传递给下一个函数。 但是,在您的情况下, C
和D
不应影响输入。 我引入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]
这就引出了一个问题:你在用resultC
和resultD
做什么? 函数式编程是关于用纯粹的、无副作用的函数编写程序。 当您难以以函数式方式表达您的程序时,有时可能表明您没有以函数式方式思考。
不是 ramda,但它可以满足您的需求。
const { pipe, tap } = require('rubico')
const A = pipe([
B,
tap(C),
tap(D),
])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.