jgr*_*gr0 6 javascript monads ramda.js ramda-fantasy fluture
我正在使用Bluebird做异步操作,但现在必须做很多空/空/错误检查,我不想按照通常的Else路线.我正在考虑使用monad,但尚未彻底完成它.
此外,我希望它能与ramda一起使用,pipe / compose因为我的大多数其他代码都整齐地封装在功能管道中.根据许多 讨论,monadic Futures(Fluture似乎被推荐)比Promises更受欢迎,对pipeP的支持和composeP可能在未来版本中被删除.
Fluture似乎是一个不错的选择,因为据说它可以很好地适应那些坚持幻想 - 土地规格的图书馆(如ramda).
但是我完全迷失了如何实现将Ramda的管道与Fluture集成在一起的东西.我需要一些示例代码的帮助.
例如:
我有一个DB调用,返回一个对象数组.数组可能具有值,为空或未定义.我有一个功能管道,可以转换数据并将其返回到前端.
示例承诺代码:
fancyDBCall1(constraints)
.then(data => {
if (!data || data.length === 0) {
return []
}
return pipe(
...
transformation functions
...
)(data)
})
.then(res.ok)
.catch(res.serverError)
Run Code Online (Sandbox Code Playgroud)
有人可以就一个好的方法提出一些指示.
Fla*_*nix 10
因此,有一些事情可以处理您的代码.但首先,我们来谈谈Monads.
在此代码中,您可以使用3种类型的Monad:
nothing)让我们稍微分解你的代码.我们要做的第一件事就是确保你的fancyDBCall1(constraints)退货Maybe.这意味着它可能返回结果,或者什么都不返回.
但是,您fancyDBCall1是异步操作.这意味着它必须返回一个Future.这里的诀窍是让它返回一个值的未来,而不是Future <Array>让它返回一个Future < Maybe Array >.
哇,听起来很复杂的先生!
想想它而不是: Future.of('world');
你有: Future.of( Maybe( 'world' ) );
还不错吧?
这样就可以避免在代码中进行空检查!以下几行将消失:
if (!data || data.length === 0) {
return []
}
Run Code Online (Sandbox Code Playgroud)
你的例子看起来像:
/*
* Accepts <Maybe Array>.
* Most ramda.js functions are FL compatible, so this function
* would probably remain unchanged.
**/
const tranform = pipe( .... );
// fancyDBCall1 returns `Future <Maybe Array>`
fancyDBCall1(constraints)
.map( transform )
.fork( always(res.serverError), always(res.ok) );
Run Code Online (Sandbox Code Playgroud)
看看我们的代码有多好看?但等等,还有更多!
所以,如果你密切关注,你知道我错过了一些东西.当然,我们现在处理一个空检查,但如果transform爆炸怎么办?好吧,你会说"我们发送res.serverError".
好.这还算公平.但是,如果transform函数因用户名无效而失败怎么办?
你会说你的服务器炸毁了,但它不是正是如此.您的异步查询很好,但我们得到的数据不是.这是我们可以预料到的,它不像流星撞击我们的服务器场,只是有些用户给了我们一封无效的电子邮件,我们需要告诉他!
这里的诀窍是改变我们的transform功能:
/*
* Accepts <Maybe Array>.
* Returns <Maybe <Either String, Array> >
**/
const tranform = pipe( .... );
Run Code Online (Sandbox Code Playgroud)
哇,耶稣香蕉!这个黑魔法是什么?
在这里我们说我们的变换可能返回Nothing或者它返回一个Either.这可能是一个字符串(左侧分支始终是错误)或一个值数组(右侧分支始终是正确的结果!).
所以,是的,这次旅行真是太糟糕了,你不是吗?为了给你一些具体的代码让你陷入困境,这里有一些代码与这些结构可能看起来像:
首先,我们有一个Future <Maybe Array>:
const { Future } = require("fluture");
const S = require("sanctuary");
const transform = S.map(
S.pipe( [ S.trim, S.toUpper ] )
);
const queryResult = Future.of(
S.Just( [" heello", " world!"] )
);
//const queryResult2 = Future.of( S.Nothing );
const execute =
queryResult
.map( S.map( transform ) )
.fork(
console.error,
res => console.log( S.fromMaybe( [] ) ( res ) )
);
Run Code Online (Sandbox Code Playgroud)
你可以玩queryResult和queryResult2.这应该可以让你很好地了解Maybe monad可以做些什么.
请注意,在这种情况下,我使用的是Sanctuary,它是Ramda的纯粹版本,因为它是Maybe类型,但你可以使用任何Maybe类型库并对它感到满意,代码的想法是相同的.
现在,让我们添加Either.
首先让我们关注我们的转换函数,我稍微修改了一下:
const validateGreet = array =>
array.includes("HELLO") ?
S.Right( array ) :
S.Left( "Invalid Greeting!" );
// Receives an array, and returns Either <String, Array>
const transform = S.pipe( [
S.map( S.pipe( [ S.trim, S.toUpper ] ) ),
validateGreet
] );
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.如果数组服从我们的条件,我们返回带有数组的Either的右分支,而不是带有错误的左分支.
现在,让我们将它添加到我们之前的示例中,它将返回一个Future <Maybe <Either <String, Array>>>.
const { Future } = require("fluture");
const S = require("sanctuary");
const validateGreet = array =>
array.includes("HELLO") ?
S.Right( array ) :
S.Left( "Invalid Greeting!" );
// Receives an array, and returns Either <String, Array>
const transform = S.pipe( [
S.map( S.pipe( [ S.trim, S.toUpper ] ) ),
validateGreet
] );
//Play with me!
const queryResult = Future.of(
S.Just( [" heello", " world!"] )
);
//Play with me!
//const queryResult = Future.of( S.Nothing );
const execute =
queryResult
.map( S.map( transform ) )
.fork(
err => {
console.error(`The end is near!: ${err}`);
process.exit(1);
},
res => {
// fromMaybe: https://sanctuary.js.org/#fromMaybe
const maybeResult = S.fromMaybe( S.Right([]) ) (res);
//https://sanctuary.js.org/#either
S.either( console.error ) ( console.log ) ( maybeResult )
}
);
Run Code Online (Sandbox Code Playgroud)
那么,这告诉我们什么?
如果我们得到异常(没有预料到的东西),我们打印The end is near!: ${err}并干净地退出应用程序.
如果我们的数据库没有返回,我们打印[].
如果DB不返回的东西和事情是无效的,我们打印"Invalid Greeting!".
如果数据库返回正常的东西,我们打印它!
嗯,是的 如果你开始使用Maybe,Either和Flutures,你需要学习很多概念,而且感到不知所措是正常的.
我个人不知道Ramda的任何好的和活跃的Maybe/Either库,(也许你可以尝试Folktale中的Maybe/Result类型?)这就是为什么我使用了Sanctuary,一个来自Ramda的克隆,它更纯粹并且很好地集成了用Fluture.
但是如果你需要从某个地方开始,你可以随时查看社区gitter聊天并发布问题.阅读文档也有很大帮助.
希望能帮助到你!
| 归档时间: |
|
| 查看次数: |
1253 次 |
| 最近记录: |