Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JavaScript中管道和单子是如何协同工作的?_Javascript_Functional Programming_Pipe_Monads - Fatal编程技术网

在JavaScript中管道和单子是如何协同工作的?

在JavaScript中管道和单子是如何协同工作的?,javascript,functional-programming,pipe,monads,Javascript,Functional Programming,Pipe,Monads,我看过类似的问题和答案,没有找到一个能直接回答我问题的答案。我正在努力理解如何将可能或与管道功能结合使用。我希望将函数连接在一起,但是如果在任何步骤中发生错误,我希望管道停止并返回错误。我正试图在node.js应用程序中实现函数式编程概念,这是我第一次认真研究这两个概念,因此没有任何答案会如此简单,以至于侮辱我在这方面的智慧 我编写了一个管道函数,如下所示: const _pipe = (f, g) => async (...args) => await g( await f(...

我看过类似的问题和答案,没有找到一个能直接回答我问题的答案。我正在努力理解如何将
可能
与管道功能结合使用。我希望将函数连接在一起,但是如果在任何步骤中发生错误,我希望管道停止并返回错误。我正试图在node.js应用程序中实现函数式编程概念,这是我第一次认真研究这两个概念,因此没有任何答案会如此简单,以至于侮辱我在这方面的智慧

我编写了一个管道函数,如下所示:

const _pipe = (f, g) => async (...args) => await g( await f(...args))

module.exports = {arguments.
    pipeAsync: async (...fns) => {
        return await fns.reduce(_pipe)
    }, 
...
    const token = await utils.pipeAsync(makeACall, parseAuthenticatedUser, syncUserWithCore, managejwt.maketoken)(x, y)  
我这样称呼它:

const _pipe = (f, g) => async (...args) => await g( await f(...args))

module.exports = {arguments.
    pipeAsync: async (...fns) => {
        return await fns.reduce(_pipe)
    }, 
...
    const token = await utils.pipeAsync(makeACall, parseAuthenticatedUser, syncUserWithCore, managejwt.maketoken)(x, y)  

钩、线和伸卡球

我不能强调你不被所有你必须学习的新术语所困扰是多么重要——函数式编程是关于函数的——也许你需要了解函数的唯一一件事是,它允许你使用一个参数来抽象程序的一部分;或者多个参数,如果需要(不需要)并且您的语言支持(通常是)

我为什么要告诉你这些?JavaScript已经有了一个非常好的API,可以使用内置的Promise.prototype对异步函数进行排序

// never reinvent the wheel
const _pipe = (f, g) => async (...args) => await g( await f(...args))
myPromise .then (f) .then (g) .then (h) ...

娜奥米克的回答很有趣,但她似乎并没有抽出时间来回答你的问题

简而言之,您的
\u pipe
函数可以很好地传播错误。并在抛出错误时立即停止运行函数

问题在于您的
pipeAsync
函数,您的想法是正确的,但是您不需要让它返回函数而不是函数的承诺

这就是为什么您不能这样做,因为它每次都会抛出一个错误:

const result = await pipeAsync(func1, func2)(a, b);
为了在当前状态下使用
pipeAsync
,您需要两个
wait
s:一个获取
pipeAsync
的结果,另一个获取调用该结果的结果:

const result = await (await pipeAsync(func1, func2))(a, b);
解决方案

pipeAsync
的定义中删除不必要的
async
wait
。组合一系列函数(甚至异步函数)的行为不是异步操作:

module.exports = {
    pipeAsync: (...fns) => fns.reduce(_pipe),
完成后,一切都很顺利:

const\u pipe=(f,g)=>async(…args)=>await g(await f(…args))
constpipeasync=(…fns)=>fns.reduce(_管道);
const makeACall=async(a,b)=>a+b;
const parseAuthenticatedUser=async(x)=>x*2;
const syncUserWithCore=async(x)=>{
抛出新错误(“nooooo!!!!”);
};
constmaketoken=async(x)=>x-3;
(异步()=>{
常数x=9;
常数y=7;
试一试{
//工作到parseAuthenticatedUser并成功完成
const token1=wait pipeAsync(
马克卡尔,
parseAuthenticatedUser
)(x,y);
console.log(token1);
//抛出syncUserWithCore
const token2=await pipeAsync(
马克卡尔,
parseAuthenticatedUser,
syncUserWithCore,
makeToken
)(x,y);
console.log(token2);
}捕获(e){
控制台错误(e);
}

})();没有您要寻找的“管道”或单子,而不是普通的函数组合
Wait
仅对承诺有帮助。这是错误的
参数。
第3行是打字错误,还是我以前从未见过的语法?您应该调用它
compAsync
,以区别于通常的函数组合。或者,即使你想装腔作势:-)@Bergi,哦,我想提一提将其作为一个不同的名称导出——谢谢你的评论。我会做一些编辑。谢谢你的回答。有些事情还不清楚。请不要陷入异步/等待的事情中。我之所以把它放在这里,是因为我需要编写的几个函数都是异步设计的,除非它一直都是异步的,否则就无法工作。我更喜欢这种语法,因为1)我熟悉C#中的语法,2)这是nodejs中最新的语法。如果我需要用“then”来做,我会做出改变。我相信我混合了太多我不懂的东西。如果我们去掉了异步性,那么如何在出现错误时中断管道呢?
async
/
await
Promise.prototype。然后
在幕后——这只是一种不同的语法——我们可以“使用
await
,但重点是要表明这样的重型机器是不必要的;当我们用一个简单的
f(x)得到我们想要的*精确行为时,那就太过分了。。。。(续):换一种方式做完全可以,但你的理由不好;1) 另一种语言(C#)的语法对JS的表达能力没有影响;2) 其他人如何选择“nodejs中最新的方式”来编写程序对你的偏好没有直接影响——最新的方式也不意味着最好——当CoffeeScript是最新的方式时,许多人将完美的JavaScript程序基础翻译成了一种死胡同语言。