反应式编程与事件驱动编程有何不同?

新手上路,请多包涵

我正在学习 JavaScript 中的反应式编程和函数式反应式编程。我很困扰。

维基百科说,有多种方法可以编写响应式代码,例如命令式、OORP 和函数式。我想知道事件驱动是否只是编写响应式代码的另一种方式?

反应式编程与 Promises 有何关系?我认为 promises 是事件驱动和回调地狱的替代方案。

原文由 Narayan Prusty 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 921
2 个回答

反应式编程与 Promises 有何关系?我认为 promise 是事件驱动和回调地狱的替代方案。

实际上,这两者是相关的,我喜欢将 Promises 称为功能响应式编程的门户药物。

 +----------------------+--------+-------------+
|                      |  Sync  |    Async    |
+----------------------+--------+-------------+
| Single value or null | Option | Promise     |
| Multiple values      | List   | EventStream |
+----------------------+--------+-------------+

可以将 Promises 视为具有一项的 EventStreams,或者您可以将 EventStreams 视为随时间变化的多个 Promises。

Promises can be chained,这越来越接近反应式编程:

 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)
})

两个代码片段做同样的事情,但是在思维上有很大的不同:使用 promises 你是在考虑以一种清晰的方式用异步步骤处理单个动作——思维是势在必行的,你是在一步步做事。使用 FRP,您可以说“用户名流是通过应用这两个转换步骤从 userIds 的流中创建的”。当您有用户名流时,不关心它们来自哪里,并说“只要有新用户名,就将其显示给用户”。

FRP 编码风格将指导您将问题建模为值流(即随时间变化的值)以及这些值之间的关系。如果您已经了解 Promises,最初的学习曲线会更容易一些,但只有当您开始以不同的方式思考和建模问题时,才能获得主要好处——可以(如果不是很有用)使用 FRP 库进行命令式编程。

原文由 OlliM 发布,翻译遵循 CC BY-SA 3.0 许可协议

反应式编程与事件驱动编程有何不同?

事件驱动编程围绕所谓的事件展开,这些事件是程序在某事发生时“触发”的抽象事物。代码中的其他地方“侦听”事件,并在事件发生时响应他们需要做的事情。例如,事件可以是“用户按下此按钮”或“打印机打印完您的文档”。

反应式编程处理 数据。归根结底,这是事件驱动编程的一个特例。事件:数据改变。事件处理程序:更改更多数据(如果适用)。当您想到电子表格时,通常会清楚这个概念。 If you set cell1 = cell2 + cell3 this implicitly sets two event handlers on the data changed events of cell2 and cell3 to update cell1 ’s data. cell1 的数据没有这样的事件处理程序,因为没有单元格依赖于它的值。


长话短说;博士;

维基百科说,有多种方法可以编写响应式代码,例如命令式、OORP 和函数式。我想知道事件驱动是否只是编写响应式代码的另一种方式?

事件驱动编程的思想与命令式、面向对象、函数式的思想是正交的。

  • 命令式编程:专注于改变你的程序的状态将实现你想要的。大多数计算机都是命令式的(与 声明式编程 相反),而高级语言有时是声明式的。相比之下,声明式编程涉及编写指定您希望它做什么而不是您希望代码如何做的代码。
  • 面向 对象 编程:处理所谓的对象,或具有相关方法的数据包。与函数式编程不同,因为方法能够访问与对象关联的数据。
  • 函数式编程:处理可重用的函数,或接受输入和输出的过程。这与 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 有何关系?

Promises 是程序执行流程的抽象,可以概括如下:

  • 提问者:每当你做完你正在做的事情时,你会给我回电话吗?
  • 回答者:没问题,我 保证

这里没什么特别的,只是它是考虑代码执行顺序的另一种方式。例如,当您调用远程机器时,promises 很有用。有了承诺,你可以说“当你从这个远程电话回来时给我回电话!”。无论您使用哪个库,它 都会承诺 在从远程机器返回信息时给您回电。通常,这很有用,因为它可以让您在不等待调用返回的情况下同时做其他事情。

妙语:有很多不同风格的代码,但它们在事件驱动和反应式编程的模式中并没有起到太大的作用。据我所知,您可以使用大多数语言进行事件驱动和/或反应式编程。

原文由 Frank Bryce 发布,翻译遵循 CC BY-SA 3.0 许可协议

推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏