我想知道是否可以将A
重写为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;
};
的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
答案 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]]]
我看到你在那里做了什么
仔细检查后,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
编写函数时,将返回值1传递给下一个函数。但是,在您的情况下,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
做了哪些 ?函数式编程是关于使用纯粹的无副作用函数编写程序。如果您在以功能方式表达自己的程序时遇到困难,有时可能表明您没有以功能性方式思考。
答案 1 :(得分:0)
不是ramda,但是它可以满足您的要求。
const { pipe, tap } = require('rubico')
const A = pipe([
B,
tap(C),
tap(D),
])