我已经开发了几年的JavaScript,我根本不理解有关承诺的大惊小怪.
似乎我所做的只是改变:
api(function(result){
api2(function(result2){
api3(function(result3){
// do work
});
});
});
Run Code Online (Sandbox Code Playgroud)
无论如何,我可以使用像async这样的库,例如:
api().then(function(result){
api2().then(function(result2){
api3().then(function(result3){
// do work
});
});
});
Run Code Online (Sandbox Code Playgroud)
哪个代码更多,可读性更低.我没有在这里获得任何东西,它也不会突然神奇地"平坦".更不用说必须将事物转换为承诺.
那么,这里的承诺有什么大惊小怪?
我主要使用Scala和JavaScript等编程语言.我试图理解在两种语言中如何使用异步响应式编程的相似点和不同点.你能帮助我吗?
我没有采用任何特定的Js Promise框架,因为它似乎很多实现了类似的规范(如Promise/A).到目前为止我只使用过Q.
似乎在Javascript中我们称之为Deferred我们解决的对象来完成一个Promise.在Scala中,似乎Promise是你决定获得Futuremonad 的对象.
有人可以告诉我这是对的吗?Promise在Js和Scala之间使用不同术语有什么好的理由吗?
此外,在Scala中,我们通常Future使用像(map和Haskell)这样的运算符进行进一步计算来链接monad .在Js中这些相当于什么?flatMapbind
我可能是错的,但在我看来,在JS中的then一个Promise种类同时处理的map和flatMap运营商吗?如果是这样,是否有可能获得一个promise of promise of resultin Js?就像我们可以Future[Future[Result]]在Scala中获得一个(Future[Result]无论如何都可以扁平化).
Js Promise是monad吗?即使方法名称与我们在monad文献中找到的名称不匹配,它似乎也是如此.
我正在努力理解JavaScript中的单元函数.特别是因为让我'得到'monad(或至少我认为)的东西是Promise对象,以及如何then总是返回一个新的Promise,无论你传递给哪个函数then,据我所知,这相当于bind或者>>=在haskell中.这对我来说是完全有意义的,因为它确保你所有的功能都在'monad universe'中执行,可以这么说.
让我振作起来的是Douglas Crockford的"Monads and Gonads"演讲.在他的实现中,bind直接返回transform函数的结果,而不检查结果本身是否为monad.这与Promises的then方法发生冲突,因为thenALWAYS会返回一个新的Promise.
一种想法是提升方法.他的实施确保'升力'将永远返回monad,并且可能then被提升到Promise.但是,这意味着then !== bind,并且Promise在某处具有内部绑定.
我的直觉是,在绑定函数中至少应该进行某种类型的检查,检查转换的结果,并允许生成的monad被允许通过,但是会拦截非monad并再次通过它们,就像'升力'确实如此.
*编辑
此外,我的印象then相当于bind, flatMap, >>=因为它有能力打开其他monad,包括不同的monads和它自己的类型.在查看JavaScript中的一些类别理论引用时,flatMap用于映射一组嵌套数组,然后将它们展平为一维.这适合于如何then等待你提供的其他承诺.但似乎与上面提到的原始实现不匹配.我感到失落.
任何拥有更多FP经验的人都会对我所缺少的东西有所了解,或者我是否太过分了,需要从头开始?
一些代码示例......
// Crockford's 'bind'
monad.bind = function(transform) {
// value was passed in through the unit constructor
return transform(value);
}
Run Code Online (Sandbox Code Playgroud)
我的麻烦区
// Set the 'isMonad' prop to be true, for all
// monads made with the MONAD macroid
monad.isMonad …Run Code Online (Sandbox Code Playgroud) 我正在尝试熟悉JavaScript中的函数式编程.我刚看到指针仿函数是:
具有
of将任何单个值放入其中的函数的对象.ES2015增加了
Array.of使数组成为一个尖锐的算符.
而我的问题是"单一价值"究竟意味着什么?
我想制作一个Functor/Container(如https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch8.html),它将给定尺寸(宽度,高度)的网格保持为一维数组,允许我对它进行转换.作为一个普通的对象,我会把它存储为{ width: 2, height: 2, list: [1, 2, 3, 4] }但我想把它放在一个仿函数中,我不知道如何正确地做.
我知道使用像这样的尖头仿函数存储单个值是完全没问题的:
Container.of(47)
Run Code Online (Sandbox Code Playgroud)
但是,如果对象是"单值",那么将对象用作值是否可以:
Grid.of({ width: 2, height: 2, list: [1, 2, 3, 4] })
Run Code Online (Sandbox Code Playgroud)
或者甚至像这样:
Grid.of(2, 2, [1, 2, 3, 4])
Run Code Online (Sandbox Code Playgroud) 我知道 Javascript 的承诺在技术上既不是 Haskell 意义上的函子也不是 monad,因为(除其他外)
bind回退到map传入纯函数时的操作(因此具有不明确的类型)Promise函数和resolve(又名return)递归地连接嵌套的 Promise通过始终提供具有正确类型的函数,可以轻松绕过第一个问题a -> Promise b。
第二个问题显然违反了参数多态函数的参数性特征,即无法构造结构m (m a)。但是这个结构在承诺/异步计算的上下文中意味着什么?我想不出Promise (Promise a), wherePromise是 monad 的有意义的语义。那么我们会失去什么呢?递归连接的含义是什么?
假设我们非常务实(这就是我们在编写 Javascript 时应该做到的),Promise如果我们考虑到边缘情况,我们不能声称 a 是 Javascript 中的 monad 吗?
在 JavaScript 中,Promises 有一个名为 的方法then,用于在成功的情况下解包结果,例如,
fetch("google.com").then(console.log)
Run Code Online (Sandbox Code Playgroud)
从这个 Haskell 的教程中,我还发现了一个类似的东西fmap,例如,
fmap putStrLn (fetch "google.com")
Run Code Online (Sandbox Code Playgroud)
它们看起来非常相似,但我不确定它们是否等效。这就是为什么我想问他们是否是同一件事。
PS:“等效”一词应与 Curry-Howard Correspondence 等效。