我正在学习JavaScript中的反应式编程和功能反应式编程.我很迷茫.
维基百科说,有各种方法来编写反应性代码,如命令式,OORP和功能性.我想知道事件驱动是否只是编写反应代码的另一种方式?
响应式编程如何与Promises相关?我认为承诺是事件驱动和回调地狱的替代品.
反应式编程与事件驱动编程有何不同?
事件驱动的编程围绕着所谓的事件,这些事件是在事情发生时编程"触发"的抽象事物.代码中的其他位置"监听"事件并响应事件发生时他们需要做的事情.例如,事件可以是"用户按下此按钮"或"打印机已完成打印文档".
反应式编程处理数据.最终,这是事件驱动编程的特例.事件:数据已更改.事件处理程序:更改一些更多数据(如果适用).当您想到电子表格时,通常会清除此概念.如果你设置cell1 = cell2 + cell3
它隐含地设置两个事件处理程序的数据更改事件cell2
和cell3
更新cell1
的数据. cell1
的数据没有这样的事件处理程序,因为没有单元格依赖于它的值.
TL; DR;
维基百科说,有各种方法来编写反应性代码,如命令式,OORP和功能性.我想知道事件驱动是否只是编写反应代码的另一种方式?
事件驱动编程的想法与命令式与OO与功能性的概念正交.
Imperitive编程:专注于改变程序的状态将实现您想要的.大多数计算机都是必要的(与声明性编程相反),而更高级别的语言有时是声明性的.相反,声明性编程处理的是编写代码,指定您希望它执行的操作,而不是您希望代码执行操作的方式.
Ø bject Ø riented编程:所谓的对象,或者与相关方法的数据包协议.与函数式编程不同,因为这些方法能够访问与对象关联的数据.
功能编程:处理可重复使用的功能,或处理输入和输出的程序.这与OO编程不同,因为传统上函数不具有将数据与输入和输出之外的函数相关联的能力.
事件驱动编程:构建程序以处理("处理")程序中发生的其他事件("事件").换句话说,它在逻辑上构建您的代码
When Event1 happens do A and B When Event2 happens do B and C
但是有很多方法可以编写这个代码,实际上有很多方法可以编写代码,有很多方法可以在功能上编写代码等等.但是这里有一些例子.
势在必行(使用事件循环):
while(true) // some other code that you need to do... if Event1 then do A do B if Event2 then do B do C
面向对象(带后台线程):
// event queue events = new EventQueue() handler = new EventHandler() // creates background thread Thread.DoInBackground(handler.listenForEvents(events)) // ... other code ... // fire an event! events.enqueue(new Event1()) // other file class EventHandler Func listenForEvents(events) while(true) while events.count > 0 newEvent = event.dequeue() this.handleEvent(newEvent) Thread.Sleep(Time.Seconds(1)) Func handleEvent(event) if event is Event1 this.A() this.B() if event is Event2 this.B() this.C() Func A() // do stuff return Func B() // do stuff return Func C() // do stuff return
功能(对事件的语言支持)
on Event(1) do Event1Handler() on Event(2) do Event2Handler() Func Event1Handler() do A() do B() Func Event2Handler() do B() do C() Func A() // do stuff return Func B() // do stuff return Func C() // do stuff return // ... some other code ... // fire! ... some languages support features like this, and others have // libraries with APIs that look a lot like this. fire Event(1)
响应式编程如何与Promises相关?
Promise是程序执行流程的抽象,可以总结如下:
阿斯克:每当你做完你正在做的事情时,你会给我回电话吗?
回答:当然,我保证
这里没什么特别的,除了它是另一种思考代码执行顺序的方法.例如,当您调用远程计算机时,promise很有用.有了承诺,你可以说"当你从这个远程呼叫返回时给我回电话!".无论您使用哪个库,都会承诺在从远程计算机返回某些内容时回拨您.通常,这很有用,因为它允许您在此期间执行其他操作而无需等待返回的调用.
打孔线:有很多不同风格的代码,但它们在事件驱动和反应式编程模式中不起太大作用.据我所知,您可以在大多数语言中进行事件驱动和/或反应式编程.
响应式编程如何与Promises相关?我认为这个承诺是事件驱动和回调地狱的替代品.
在实践中这两者是相关的,我喜欢称Promises为功能反应式编程的门户药物.
+----------------------+--------+-------------+ | | Sync | Async | +----------------------+--------+-------------+ | Single value or null | Option | Promise | | Multiple values | List | EventStream | +----------------------+--------+-------------+
Promise可以被认为是带有一个项目的EventStreams,或者你可以将EventStreams视为多个Promise随着时间的推移.
Promise可以链接,接近响应式编程:
getUser() // return promise .then((userId) => { return fetch("/users/"+userId) }) .then((user) => { alert("Fetched user: " + user.name) })
与bacon.js相同:
const userStream = userIdStream // EventStream of userIds .flatMapLatest((userId) => { return Bacon.fromPromise(fetch("/users/"+userId)) }) const userNameStream = userStream.map((user) => user.name) userNameStream.onValue((user) => { alert("Fetched user: " + user.name) })
两个代码片段都做同样的事情,但思维方面存在很大差异:对于承诺,您正在考虑以明确的方式使用异步步骤处理单个操作 - 思维是必要的,您正在逐步完成工作.使用FRP,您会说" userIds
通过应用这两个转换步骤从流中创建用户名流".如果您拥有一组用户名,而不关心他们来自何处,并说"只要有新用户名,请将其显示给用户".
FRP编码样式将指导您将问题建模为值流(即随时间变化的值)以及这些值之间的关系.如果您已经了解Promises,那么初始学习曲线会更容易一些,但只有当您开始思考并以不同方式对问题建模时才能获得主要好处 - 使用FRP库进行命令式编程是可能的(如果不是非常有用).