til*_*lda 59 asynchronous clojure frp reactive-programming core.async
在将Clojure的core.async与所谓的Reactive Extensions(Rx)和FRP进行比较时,我似乎有点困惑.他们似乎解决了类似的异步 - 长期问题,所以我想知道什么是主要差异,在什么情况下优先于另一个.有人可以解释一下吗?
编辑:为了鼓励更深入的答案,我想让问题更具体:
Core.async允许我编写同步代码.但是据我所知,FRP只需要一级嵌套回调(处理逻辑的所有函数都作为参数传递给FRP API).这似乎两种方法都不需要回调金字塔.确实,在JS中我必须写function() {...}
多次,但主要问题,嵌套回调,也在FRP中消失了.我做对了吗?
" FRP通过控制流完善了信息的沟通"你能(某人)请给出更具体的解释吗?
我不能像通过频道那样绕过FRP的可观察端点吗?
总的来说,我理解历史上两种方法的来源,我在这两种方法中都尝试了很少的教程.然而,我似乎被差异的非显而易见性"瘫痪"了.是否有一些代码难以在其中一种中编写而使用另一种代码很容易?那架构原因是什么?
Gui*_*ler 31
我认为主要的问题是你对解决问题的假设并不是这样,因为他们都没有解决异步性 "问题".
FRP
主要思想是传播变化,考虑完成Excel所做的事情,在级联中依赖于彼此定义细胞,当一个细胞发生变化时,重新计算级联中的所有依赖细胞.
core.async
主要的想法是系统分解,认为queue
在不同的过程中使用a分离关注点,core.async
如果不是队列,你有渠道,但你得到了想法.
因此,删除金字塔形代码不是任何一种技术的目标,它们在不同的抽象层上运行.
关于收集通信和流量控制的想法取自原始的核心异步帖子.
虽然有各种机制可以使事件/回调更清晰(FRP,Rx/Observables),但它们并没有改变它们的基本性质,即在一个事件上运行任意数量的其他代码,可能在同一个线程上,导致诸如"不要在你的处理程序中做太多工作"的警告,以及像"回调地狱"这样的短语.
重新定义,如果在事件处理程序中有业务域代码,则已将X事件处理与X发生时的操作进行了比较.
这就是core.async
铲球,因为引入队列/通道的中间,有助于为中分类.
关于回调和将可观察端点作为参数传递的所有问题都只是实现问题,它实际上取决于Rx
实现和API.
如果你看一下React可重用的组件,你真的没有太多的回调地狱可见,你就会想到传递可观察的东西.
即使Rx
可以用于建模任何数据流,更常用于UI渲染 a-la Excel,以简化模型更改时更新视图的方式.
另一方面,Core.Async
当任何两个子系统相互通信(与队列相同的使用场景)时,可以用来模拟关注点的分离,在UI渲染链上使用它的主要思想是分离:
因此,您可以拥有core.async
并FRP
在一起,因为core.async
它将分离关注点,并FRP
在您的模型更新后定义级联数据流.
osk*_*rkv 23
至少有一个主要的主要差异,以及我认为,"[FRP]通过控制流完成信息传播"的Rich,如下所示.
回调是执行的代码.并且该执行必须在某个时间点在某个线程中发生.通常,时间是事件发生的时间,而线程是注意/产生事件的线程.如果生产者改为在频道上放置消息,您可以随意使用消息,无论您想要什么线程.因此,回调本质上是一种通信形式,通过指示回调代码执行的时间和地点,将通信与控制流程进行比较.如果由于某种原因必须使用回调,只需使用它们在队列/通道上放置一条消息就可以恢复正常.
因为core.async不那么复杂,所以只要没有充分的理由使用替代方案,它应该是首选的.
noi*_*ith 11
Clojure core.async是Go语言的go块的一个端口.基本概念是表示线程之间异步通信的通道.
目标是能够编写正常的顺序代码块,访问通道以获取输入,并将其无缝转换为状态机,为您计算CSP转换.
与FRP形成鲜明对比,FRP仍然基本上是关于回调,它通过控制流完成了消息的通信.core.async完全消除了代码中的回调,并将控制流与消息传输分开.此外,在FRP中,通道不是第一类对象(即,您不能将FRP通道作为FRP通道上的值发送).
编辑:
回答你的问题:
是的,很多时候,可以消除回调,例如使用重试逻辑,distinctUntilChanged以及许多其他内容,例如:
var obs = getJSON('story.json').retry(3);
var obs = Rx.Observable.fromEvent(document, 'keyup').distinctUntilChanged();
我不确定这与流量控制使其更复杂有关.
是的,你可以传递像通道一样的对象,就像下面的对象一样.
例如,您可以使用RxJS和ReplaySubject在此处拥有类似通道的行为:
var channel = new Rx.ReplaySubject();
// Send three observables down the chain to subscribe to
channel.onNext(Rx.Observable.timer(0, 250).map(function () { return 1; }));
channel.onNext(Rx.Observable.timer(0, 1000).map(function () { return 2; }));
channel.onNext(Rx.Observable.timer(0, 1500).map(function () { return 3; }));
// Now pass the channel around anywhere!
processChannel(channel);
Run Code Online (Sandbox Code Playgroud)
为了让多一点具体的,比较从大卫·诺伦的职位代码这里有RxJS FRP例子在这里