2015-12-28 16 views
22

Sto imparando la programmazione reattiva e la programmazione reattiva funzionale in JavaScript. Sono molto confuso.In che modo la programmazione reattiva è diversa dalla programmazione basata sugli eventi?

Wikipedia dice che ci sono vari modi per scrivere codice reattivo come imperativo, OORP e funzionale. Voglio sapere se event-driven è solo un altro modo per scrivere codice reattivo?

In che modo la programmazione reattiva è correlata a Promises? Penso che le promesse siano un'alternativa all'inferno di callback e di eventi.

+2

correlati: [Vantaggio della programmazione reattiva funzionale su event-listeners] (http://stackoverflow.com/q/23848221/6445533) – ftor

+0

Check out: https://www.oreilly.com/ideas/reactive-programming -vs-reactive-systems – XML

risposta

17

In che modo la programmazione reattiva è correlata a Promises? Penso che la promessa sia un'alternativa all'inferno di callback e di eventi.

In pratica i due sono correlati, mi piace chiamare Promises un gateway di droga per la programmazione reattiva funzionale.

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

promesse possono essere pensati come EventStreams con una sola voce, oppure si può pensare di EventStreams come molteplici promesse nel corso del tempo.

promesse possono essere concatenati, che è sempre vicino alla programmazione reattiva:

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

Lo stesso con bacon.js:

const userStream = userIdStream // EventStream of userIds 
    .flatMapLatest((userId) => { 
     return Bacon.fromPromise(fetch("https://stackoverflow.com/users/"+userId)) 
    }) 
const userNameStream = userStream.map((user) => user.name) 
userNameStream.onValue((user) => { 
    alert("Fetched user: " + user.name) 
}) 

Entrambi i frammenti di codice fanno la stessa cosa, ma c'è un grande differenza di pensiero: con le promesse stai pensando di gestire una singola azione con passaggi asincroni in modo chiaro - il pensiero è imperativo, stai facendo le cose passo dopo passo. Con FRP, si dice "uno stream di nomi utente viene creato dallo stream di userIds applicando questi due passaggi di trasformazione". Quando hai un flusso di nomi utente, senza preoccuparti da dove provengono, e dì "ogni volta che c'è un nuovo nome utente, mostralo all'utente".

Lo stile di codifica FRP consente di modellare il problema come flusso di valori (ovvero i valori che cambiano nel tempo) e le relazioni tra questi valori. Se conosci già Promises, la curva di apprendimento iniziale sarà un po 'più semplice, ma il vantaggio principale si ottiene solo quando inizi a pensare e modellare il problema in modo diverso - è possibile (se non molto utile) fare una programmazione imperativa con le librerie FRP.

42

In che modo la programmazione reattiva è diversa dalla programmazione a evento?

La programmazione guidata dagli eventi ruota intorno ai cosiddetti eventi, che sono cose astratte che i programmi "sparano" quando qualcosa accade. Altri posti nel tuo codice "ascoltano" gli eventi e rispondono con ciò che devono fare quando accade quell'evento. Ad esempio, un evento potrebbe essere "l'utente ha premuto questo pulsante" o "la stampante ha finito di stampare il documento".

La programmazione reattiva riguarda i dati . In definitiva, questo è un caso speciale di programmazione basata sugli eventi. L'evento: i dati sono cambiati. Il gestore di eventi: modifica alcuni altri dati (se applicabile). Questo concetto viene solitamente risolto quando si pensa a un foglio di calcolo. Se si imposta cell1 = cell2 + cell3, in modo imprevisto vengono impostati due gestori di eventi sugli eventi modificati di dati di cell2 e cell3 per aggiornare i dati di cell1. I dati di cell1 non hanno un gestore di eventi di questo tipo, poiché nessuna cella dipende dal suo valore.


TL; DR;

Wikipedia dice che ci sono vari modi per scrivere codice reattivo come imperativo, OORP e funzionale. Voglio sapere se event-driven è solo un altro modo per scrivere codice reattivo?

L'idea della programmazione basata sugli eventi è ortogonale all'idea di imperativo rispetto a OO rispetto a funzionale.

  • Imperitive programming: si concentra sulla modifica dello stato del programma per ottenere ciò che si desidera. La maggior parte dei computer è indispensabile (al contrario di declarative programming), mentre i linguaggi di livello superiore sono a volte dichiarativi. La programmazione dichiarativa, al contrario, riguarda il codice di scrittura che specifica COSA vuoi che faccia, piuttosto che COME vuoi che il codice lo faccia.
  • Object Oriented programming: si occupa di cosiddetti oggetti o sacchi di dati con metodi associati. Differisce dalla programmazione funzionale perché i metodi sono in grado di accedere ai dati associati agli oggetti.
  • Functional programming: si occupa di funzioni riutilizzabili o procedure che prendono input e output. Questo differisce dalla programmazione OO perché le funzioni tradizionalmente non hanno la capacità di associare i dati con una funzione diversa dagli input e dagli output.

Event driven programming: struttura il programma per gestire ("handle") qualcos'altro che accade nel programma (un "evento").In altre parole, le strutture il codice logicamente come questo

When Event1 happens 
    do A and B 

When Event2 happens 
    do B and C 

Ma ci sono molti modi per scrivere questo codice, e infatti molti modi per scrivere il codice in modo imperativo, molti modi di scriverlo in modo funzionale, ecc Qui ci sono alcuni esempi, però.

imperativamente (con un ciclo di eventi):

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

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

Object Oriented (con thread in background):

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

funzionale (Con il supporto per la lingua per gli eventi)

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) 

In che modo la programmazione reattiva è correlata a Promises?

promesse sono un'astrazione del flusso di esecuzione del programma, che può essere riassunta come segue:

  • Richiedente: Ogni volta che il gioco è fatto fare quello che stai facendo, mi avrebbe richiamarti?
  • Answerer: Sicuro, io prometto

Niente di speciale qui, tranne che è un altro modo di pensare l'ordine in cui viene eseguito il codice. Ad esempio, le promesse sono utili quando si effettua una chiamata a una macchina remota. Con le promesse, puoi dire "richiamami quando torni da questa chiamata remota!". Qualunque libreria tu usi, allora promette che ti richiamerà quando tornerà qualcosa dal computer remoto. Spesso, questo è utile perché ti permette di fare qualcos'altro nel frattempo senza aspettare che la chiamata torni.

Punch line: ci sono molti stili diversi di codice, ma non giocano un ruolo troppo grande nel modello di programmazione guidata da eventi e reattivo. Per quanto ne so, puoi programmare eventi guidati e/o reattivi nella maggior parte delle lingue.

+0

Risposta davvero eccellente –

+0

Le promesse, criticamente, sono più di un semplice flusso di esecuzione: sono un modello di persistenza, che rappresenta lo stato di tale esecuzione e il suo output finale. Poiché sono persistenti, possono essere archiviati, condivisi, referenziati, passati. Considerando che, in un sistema puramente basato sugli eventi, ti manca la cronologia se inizi ad ascoltare dopo-il-fatto, e tu (in genere) devi ascoltare tutti gli eventi, ascoltare qualsiasi evento. Una promessa ti dà la possibilità di incapsulare e sottoscrivere un flusso di eventi limitato, a scopo singolo, e anche di verificare lo stato di quel flusso di eventi in qualsiasi momento nel futuro. – XML

+0

Nel complesso, questo post è un'ottima lettura dei principi. Per ulteriori informazioni, consultare: https://www.oreilly.com/ideas/reactive-programming-vs-reactive-systems – XML

1

Per me è come paragonare le arance alle mele. Proviamo a definire in modo semplice ciò che è e distinguere così le cose:

La programmazione reattiva è un paradigma di programmazione che viene applicato quando si desidera ottenere una funzionalità simile al binding di dati in librerie come KnockoutJS. Un esempio potrebbe essere anche le formule di Excel: tutte le celle sono come variabili in memoria. Ci sono quelli che semplicemente contengono alcuni dati e quelli che sono calcolati da quei dati. Se il primo cambia, anche il secondo. Fai attenzione che il paradigma riguarda l'implementazione di livello inferiore; quando qualcuno parla di programmazione reattiva si riferisce ai dati, ai suoi cambiamenti e a cosa succede quando si muta.

D'altra parte, la programmazione basata sugli eventi riguarda l'architettura di sistema. Secondo quel paradigma, gli eventi e gli organizzatori di eventi sono la base di un sistema e tutto è costruito sopra e attorno a loro. Esempi comuni sarebbero l'interfaccia utente e il multiplexing del server web. Senti come tutto questo è diverso? Il paradigma viene applicato a livello di un intero sistema o di un sottosistema.

In che modo la programmazione reattiva è correlata a Promises? Penso che le promesse siano un'alternativa all'inferno basato su eventi e callback.

Promise è uno strumento per ottenere simultaneità e ordine di esecuzione specifico. Può essere utilizzato in qualsiasi paradigma.

In pratica i paradigmi servono a scopi diversi ea diversi livelli. È possibile avere un design basato sugli eventi con alcuni bit di codice reattivo. È possibile avere un sistema distribuito che utilizza schemi di progettazione reattivi. Tuttavia, gli eventi sono in definitiva un concetto di livello superiore. Reattivo riguarda i dati e la loro rivalutazione, un approccio per l'implementazione o il suo dettaglio, e gli eventi sono qualcosa che nasce spontaneamente da un caso e guidi il tuo design.

0

La programmazione reattiva riguarda esclusivamente i flussi, potrebbero essere flussi di eventi o qualsiasi altra cosa. Sta emettendo/annunciando questi flussi o sottoscrivendo/guardando questi flussi o le trasformazioni di streaming che portano ad alcuni eventi. Quindi entrambi i paradigmi di programmazione sono correlati.

Problemi correlati