webentwicklung-frage-antwort-db.com.de

Wie unterscheidet sich reaktive Programmierung von ereignisgesteuerter Programmierung?

Ich lerne reaktive Programmierung und funktionale reaktive Programmierung in JavaScript. Ich bin sehr verwirrt.

Laut Wikipedia gibt es verschiedene Möglichkeiten, um reaktiven Code zu schreiben, z. B. Imperativ, OORP und funktional. Ich möchte wissen, ob ereignisgesteuert nur eine andere Möglichkeit ist, reaktiven Code zu schreiben.

Wie hängt reaktive Programmierung mit Versprechen zusammen? Ich denke, Versprechen sind eine Alternative zur ereignisgesteuerten Hölle und zum Rückruf.

33
Narayan Prusty

Wie hängt reaktive Programmierung mit Versprechen zusammen? Ich denke, das Versprechen ist eine Alternative zur ereignisgesteuerten und Callback-Hölle.

In der Praxis sind die beiden verwandt, ich nenne Promises gerne ein Gateway-Medikament zur funktionalen reaktiven Programmierung.

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

Versprechungen können als EventStreams mit einem Element oder als mehrere Versprechungen im Laufe der Zeit betrachtet werden.

Versprechen können verkettet werden, was der reaktiven Programmierung nahe kommt:

getUser() // return promise
   .then((userId) => {
       return fetch("/users/"+userId)
   })
   .then((user) => {
       alert("Fetched user: " + user.name)
   })

Das selbe mit 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)
})

Beide Code-Schnipsel machen dasselbe, aber es gibt einen großen Unterschied im Denken: Mit Versprechungen denken Sie darüber nach, eine einzelne Aktion mit asynchronen Schritten klar und deutlich zu handhaben - das Denken ist unerlässlich, Sie tun Dinge Schritt für Schritt. Mit FRP erhalten Sie den Spruch "Durch Anwenden dieser beiden Transformationsschritte wird aus dem Stream von userIds ein Stream von Benutzernamen erstellt". Wenn Sie über einen Strom von Benutzernamen verfügen, ohne sich darum zu kümmern, woher sie stammen, und sagen Sie "Wenn ein neuer Benutzername vorhanden ist, zeigen Sie ihn dem Benutzer an".

Der FRP-Codierungsstil hilft Ihnen dabei, Ihr Problem als Wertestrom (d. H. Werte, die sich mit der Zeit ändern) und die Beziehungen zwischen diesen Werten zu modellieren. Wenn Sie Promises bereits kennen, wird die anfängliche Lernkurve ein bisschen einfacher sein, aber der Hauptvorteil wird erst dann erzielt, wenn Sie anfangen, das Problem anders zu denken und zu modellieren - es ist möglich (wenn nicht sehr nützlich), eine zwingende Programmierung mit FRP-Bibliotheken durchzuführen.

22
OlliM

Wie unterscheidet sich reaktive Programmierung von ereignisgesteuerter Programmierung?

Ereignisgesteuertes Programmieren dreht sich um sogenannte Ereignisse, die abstrakte Dinge sind, die "Feuer" programmieren, wenn etwas passiert. Andere Stellen in Ihrem Code "lauschen" den Ereignissen und antworten mit dem, was sie tun müssen, wenn dieses Ereignis eintritt. Ein Ereignis könnte beispielsweise "Benutzer hat diese Taste gedrückt" oder "Der Drucker hat das Drucken Ihres Dokuments abgeschlossen" sein.

Die reaktive Programmierung befasst sich mit Daten . Letztendlich ist dies ein Sonderfall der ereignisgesteuerten Programmierung. Das Ereignis: Daten geändert. Die Ereignisbehandlungsroutine: Ändern Sie ggf. weitere Daten. Dieses Konzept wird normalerweise geklärt, wenn Sie an eine Tabelle denken. Wenn Sie cell1 = cell2 + cell3 dies setzt implizit zwei Event-Handler für die datenveränderten Ereignisse von cell2 und cell3 aktualisieren cell1 's Daten. cell1s Daten haben keine solche Ereignisbehandlungsroutine, da keine Zellen von ihrem Wert abhängen.


TL; DR;

Laut Wikipedia gibt es verschiedene Möglichkeiten, um reaktiven Code zu schreiben, z. B. Imperativ, OORP und funktional. Ich möchte wissen, ob ereignisgesteuert nur eine andere Möglichkeit ist, reaktiven Code zu schreiben.

Die Idee der ereignisgesteuerten Programmierung ist orthogonal zur Idee von imperativ vs. OO vs. funktional.

  • Imperitive Programmierung : Wenn Sie den Status Ihres Programms ändern, werden Sie das erreichen, was Sie wollen. Die meisten Computer sind zwingend erforderlich (im Gegensatz zu deklarative Programmierung ), wohingegen Sprachen höherer Ebenen manchmal deklarativ sind. Im Gegensatz dazu wird beim deklarativen Programmieren Code geschrieben, der angibt, WAS der Code tun soll, und nicht, wie der Code es tun soll.
  • [~ # ~] o [~ # ~] bject [~ # ~] o [ ~ # ~] rientierte Programmierung : befasst sich mit sogenannten Objekten oder Datenbeuteln mit zugehörigen Methoden. Unterscheidet sich von der funktionalen Programmierung, da die Methoden auf die mit den Objekten verknüpften Daten zugreifen können.
  • Funktionale Programmierung : behandelt wiederverwendbare Funktionen oder Prozeduren, die Ein- und Ausgänge annehmen. Dies unterscheidet sich von der OO Programmierung, da Funktionen normalerweise nicht in der Lage sind, Daten einer anderen Funktion als den Ein- und Ausgängen zuzuordnen.

Ereignisgesteuertes Programmieren : strukturiert Ihr Programm, um mit etwas anderem umzugehen ("umgehen"), das in Ihrem Programm passiert (ein "Ereignis"). Mit anderen Worten, es strukturiert Ihren Code logisch so

When Event1 happens
    do A and B

When Event2 happens
    do B and C

Es gibt jedoch viele Möglichkeiten, diesen Code zu schreiben, und in der Tat viele Möglichkeiten, den Code zwingend zu schreiben, viele Möglichkeiten, ihn funktional zu schreiben usw. Hier sind jedoch einige Beispiele.

Unbedingt (mit einer Ereignisschleife):

while(true)
    // some other code that you need to do...

    if Event1 then
        do A
        do B
    if Event2 then
        do B
        do C

Objektorientiert (mit Hintergrundfaden):

// 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

Funktional (mit Sprachunterstützung für Events)

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)

Wie hängt reaktive Programmierung mit Versprechen zusammen?

Versprechen sind eine Abstraktion des Programmablaufs, die sich wie folgt zusammenfassen lässt:

  • Fragender: Würdest du mich zurückrufen, wenn du fertig bist mit dem, was du tust?
  • Anrufbeantworter: Klar, ich verspreche

Hier gibt es nichts Besonderes, außer dass man sich die Reihenfolge, in der der Code ausgeführt wird, anders vorstellen kann. Beispielsweise sind Versprechungen nützlich, wenn Sie einen Remote-Computer anrufen. Mit Versprechungen können Sie sagen "Rufen Sie mich zurück, wenn Sie von diesem Ferngespräch zurückkehren!". Welche Bibliothek Sie auch benutzen verspricht , Sie zurückzurufen, wenn etwas von der entfernten Maschine zurückkommt. Dies ist oft nützlich, da Sie in der Zwischenzeit etwas anderes tun können, ohne auf die Rückkehr des Anrufs zu warten.

Punch Line: Es gibt viele verschiedene Codestile, aber sie spielen im Muster der ereignisgesteuerten und reaktiven Programmierung keine allzu große Rolle. Meines Wissens können Sie in den meisten Sprachen ereignisgesteuert und/oder reaktiv programmieren.

68
Frank Bryce

Beim reaktiven Programmieren dreht sich alles um Streams, es können Streams von Ereignissen oder alles andere sein. Es geht darum, diese Streams zu senden/anzukündigen oder diese Streams oder Stream-Transformationen zu abonnieren/anzusehen, die zu bestimmten Ereignissen führen. Beide Programmierparadigmen hängen also zusammen.

0
kg11

Für mich ist es, als würde man Orangen mit Äpfeln vergleichen. Versuchen wir auf einfache Weise zu definieren, was was ist und unterscheiden so die Dinge:

Reaktive Programmierung ist ein Programmierparadigma, das angewendet wird, wenn eine Funktionalität erreicht werden soll, die der Datenbindung in Bibliotheken wie KnockoutJS ähnelt. Ein Beispiel wären auch Excel-Formeln: Alle Zellen sind wie Variablen im Speicher. Es gibt solche, die einfach einige Daten enthalten, und solche, die aus diesen Daten berechnet werden. Wenn sich das erstere ändert, ändert sich auch das letztere. Achten Sie darauf, dass es sich bei dem Paradigma um eine Implementierung auf niedrigerer Ebene handelt. Wenn jemand von reaktiver Programmierung spricht, bezieht er sich auf Daten, ihre Änderungen und was passiert, wenn sie mutieren.

Andererseits geht es bei der ereignisgesteuerten Programmierung um die Systemarchitektur. Nach diesem Paradigma bilden Ereignisse und Ereignisbehandlungsroutinen die Grundlage eines Systems, auf dem und um das alles aufgebaut ist. Häufige Beispiele sind UI- und Webserver-Multiplexing. Fühlst du, wie das alles anders ist? Das Paradigma wird auf der Ebene eines gesamten Systems oder eines Subsystems angewendet.

Wie hängt reaktive Programmierung mit Versprechen zusammen? Ich denke, Versprechen sind eine Alternative zur ereignisgesteuerten Hölle und zum Rückruf.

Promise ist ein Tool zum Erreichen von Parallelität und bestimmter Ausführungsreihenfolge. Es kann in jedem Paradigma verwendet werden.

In der Praxis dienen die Paradigmen unterschiedlichen Zwecken und auf unterschiedlichen Ebenen. Sie können ein ereignisgesteuertes Design mit einigen Bits reaktiven Codes haben. Sie können ein verteiltes System haben, das reaktive Entwurfsmuster verwendet. Ereignisse sind jedoch letztendlich ein übergeordnetes Konzept. Bei Reactive geht es um Daten und deren Neubewertung, um einen Ansatz für die Implementierung oder um deren Details, und Ereignisse sind etwas, das natürlich aus einem Fall stammt und Ihr Design bestimmt.

0
Orif Khodjaev