Javascript 用承诺让R.管道工作? 背景
我有一个简单的代码,它包含打印函数Javascript 用承诺让R.管道工作? 背景,javascript,functional-programming,ramda.js,Javascript,Functional Programming,Ramda.js,我有一个简单的代码,它包含打印函数Hello Mars: var greeting = () => "Hello "; var dbQuery = str => Promise.resolve( `${str} Mars` ); var phrase = R.pipeP( greeting, dbQuery, R.flip( R.concat )("!") ); phrase(); 问题 我使用的是pipeP,因为dbQuery返回一个承诺。我的印象是
Hello Mars代码>:
var greeting = () => "Hello ";
var dbQuery = str => Promise.resolve( `${str} Mars` );
var phrase = R.pipeP(
greeting,
dbQuery,
R.flip( R.concat )("!")
);
phrase();
问题
我使用的是pipeP
,因为dbQuery
返回一个承诺。我的印象是,如果我将整个代码转换为承诺,pipe
可以工作,但是我真的想避免这种情况
我的想法是在Ramda中创建类似于flatMap
,也称为chain
,但这也不起作用
问题:
如果不将所有内容转换为承诺,我如何使此代码正常工作
一旦您处理Promise/Task/Future,就不可避免地要处理异步数据和程序流
如果不将所有内容转换为承诺,我如何使此代码正常工作
你指的是这部分吗
// ...
phrase();
出于同样的原因,三元运算符?:
强制您包括条件调用的两个分支,异步调用期望您处理Promise/Task/Future的成功分支和错误分支
// ...
phrase().then(onSuccess, onError);
当然,没有什么能阻止你这么做
const main = () =>
phrase().then(console.log, console.error)
main()
如前所述,Pippep(和composeP)是。我们可以通过添加一个简单的然后
函数来修复您的程序,该函数很容易插入到正常的管道
(或组合
)函数序列中
const问候语=()=>“你好”;
constdbquery=str=>Promise.resolve(`${str}Mars`);
const then=R.curry((f,p)=>p.then(f))
常量短语=R.pipe(
招呼
dbQuery,
然后(R.flip(R.concat)(“!”))
);
短语().then(console.log,console.error);
//你好,火星!
//=>{Promise'Hello Mars!'}
Ramda现在包括then和Others函数,因此最好使用这些函数:
我在下面编写了以下帮助函数,可以解决您的问题。它平等地处理承诺和非承诺数据。它还检查返回承诺的数组,如果是,则使用Promise.all
处理它们。正如预期的那样,它的最终结果将是一个承诺
function asyncPipe(...funcs){
const reducer = async (val, func) => func(await (Array.isArray(val) ? Promise.all(val): val));
return async val => await R.reduce(reducer, val, funcs)
}
以下是如何使用asyncPipe
解决原始代码问题:
function asyncPipe(...funcs){
const reducer = async (val, func) => func(await (Array.isArray(val) ? Promise.all(val): val));
return async val => await R.reduce(reducer, val, funcs)
}
var greeting = () => "Hello ";
var dbQuery = str => Promise.resolve( `${str} Mars` );
var phrase = asyncPipe(
greeting,
dbQuery,
R.flip( R.concat )("!")
);
phrase().then(console.log);
不带Ramda的情况下,正常地写它怎么样?检查讨论-以及在那里链接的讨论。简言之,Ramda团队认为pippep
(和composeP
)是一种古老的做事方式。@raina77如果问候
是一种承诺,那么这可能会奏效。然而,事实并非如此。当管道中的第一个值不是合成值时,如何使其工作?您希望使用返回承诺的操作合成一个空函数。这根本不起作用,拉姆达抱怨是对的。我知道拉姆达为什么抱怨。我从没说过拉姆达错了。我在我的帖子中明确了这一点,甚至提出了我不喜欢的修复建议。我希望在Ramda中看到then
helper函数。你的例子解释了我需要知道的一切。谢谢不知怎的,拉姆达团队在这个问题上偏离了方向,但我们做到了。@ScottSauyet你不打算反对pippep
使用期货吗?我们打算反对pippep
,因为我们更喜欢像Futures
这样的合法类型,我们将添加,然后添加,以允许Promise用户仍能获得合理的体验。我们仍在计划,但最近进展缓慢。如果您想在链中添加更多功能,该怎么办?比如constphrase=R.pipe(问候语,dbQuery,然后(R.flip(R.concat)(“!”)),R.concat(“!”)代码>。在dbQuery之后是否始终需要使用然后?