2015-12-28 17 views
22

Я изучаю реактивное программирование и функциональное реактивное программирование в JavaScript. Я очень смущен.Как реактивное программирование отличается от программирования, управляемого событиями?

Wikipedia говорит, что существуют различные способы написания реактивного кода, такого как императив, OORP и функционал. Я хочу знать, является ли управляемый событиями просто еще один способ написать реактивный код?

Как реактивное программирование связано с обещаниями? Я думаю, что обещания - это альтернатива адвентизму и обратному адду.

+2

, связанный: [Преимущество функционального реактивного программирования над событиями-слушателями] (http://stackoverflow.com/q/23848221/6445533) – ftor

+0

Выезд: https://www.oreilly.com/ideas/reactive-programming -vs-реактивные системы – XML

ответ

17

Как реактивное программирование связано с обещаниями? Я думаю, что обещание - это альтернатива адскому делу и обратному адду.

На практике эти два связаны друг с другом, мне нравится называть Promise лекарством шлюза функциональным реактивным программированием.

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

Promises можно рассматривать как EventStreams с одним элементом, или вы можете думать о EventStreams как множественные Promises в течение долгого времени.

Обещание может быть приковано, который приближается к реактивным программированию:

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

То же самое с 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) 
}) 

Оба фрагмента кода делает то же самое, но есть большая разница в мышлении: с обещаниями вы думаете об управлении одним действием с асинхронными шагами в ясной форме - мышление обязательно, вы делаете что-то шаг за шагом. С FRP вы говорите: «поток имен пользователей создается из потока userIds, применяя эти два шага преобразования». Когда у вас есть поток имен пользователей, не заботясь о том, откуда они пришли, и говорите «всякий раз, когда появляется новое имя пользователя, покажите его пользователю».

Стиль кодирования FRP поможет вам моделировать вашу проблему как поток значений (т. Е. Значения, которые меняются со временем) и отношения между этими значениями. Если вы уже знаете Promises, начальная кривая обучения будет немного легче, но основное преимущество будет достигнуто только тогда, когда вы начнете думать и моделировать проблему по-другому - возможно (если не очень полезно) делать императивное программирование с помощью библиотек FRP.

42

Как реактивное программирование отличается от программирования, управляемого событиями?

Программирование, управляемое событиями, вращается вокруг так называемых событий, которые являются абстрактными вещами, которые запускают «огонь», когда что-то происходит. Другие места в вашем коде «слушать» события и отвечать тем, что им нужно делать, когда это событие происходит. Например, событием может быть «пользователь нажал эту кнопку» или «принтер выполнил печать вашего документа».

Реактивное программирование связано с данными. В конечном счете это особый случай программирования, управляемого событиями. Событие: данные изменены. Обработчик событий: измените некоторые данные (если применимо). Эта концепция обычно очищается, когда вы думаете о таблице. Если вы установили cell1 = cell2 + cell3, это неявно устанавливает два обработчика событий в событиях с измененными данными cell2 и cell3 для обновления данных cell1. Данные cell1 не имеют такого обработчика событий, потому что никакие ячейки не зависят от его значения.


TL; DR;

Wikipedia говорит, что существуют различные способы написания реактивного кода, такого как императив, OORP и функционал. Я хочу знать, является ли управляемый событиями просто еще один способ написать реактивный код?

Идея программирования, управляемая событиями, ортогональна идее императива против ОО по сравнению с функциональным.

  • Imperitive programming: основное внимание уделяется изменению состояния вашей программы, которая будет достигать того, чего вы хотите. Большинство компьютеров являются обязательными (в отличие от declarative programming), тогда как языки более высокого уровня иногда являются декларативными. Напротив, декларативное программирование касается написания кода, который указывает, ЧТО вы хотите, а не КАК вы хотите, чтобы код выполнял это.
  • Object Oriented programming: относится к так называемым объектам или мешкам данных со связанными методами. Отличается от функционального программирования, потому что методы имеют доступ к данным, связанным с объектами.
  • Functional programming: относится к повторно используемым функциям или процедурам, которые принимают входы и выходы. Это отличается от программирования OO, поскольку функции традиционно не имеют возможности связывать данные с функцией, отличной от входов и выходов.

Event driven programming: структурирует вашу программу, чтобы иметь дело с («ручкой»), что-то еще, что происходит в вашей программе («событие»).Другими словами, структурирует код логически, как это

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) 

Как реактивное программирование связано с обещаниями?

Обещания абстракция потока выполнения программы, которые можно резюмировать следующим образом:

  • Автор вопроса: Всякий раз, когда вы закончите делать то, что вы делаете, вы бы мне перезвонить?
  • Отвечающий: Конечно вещь, я обещаю

ничего особенного здесь, за исключением того, что это еще один способ думать о том порядке, в котором выполняется код. Например, обещания полезны при обращении к удаленной машине. С обещаниями вы можете сказать «перезвоните мне, когда вернетесь с этого удаленного звонка!». Какую бы библиотеку вы ни использовали, обещает, чтобы перезвонить вам, когда она что-то вернет с удаленной машины. Часто это полезно, потому что он позволяет вам делать что-то еще, не дожидаясь возврата вызова.

Punch line: существует много разных стилей кода, но они не играют слишком большой роли в шаблоне управляемого событиями и реактивного программирования. Насколько мне известно, на большинстве языков вы можете управлять событиями и/или реактивным программированием.

+0

Действительно отличный ответ –

+0

Обещания, критически, являются не просто потоком исполнения: они являются моделью персистентности, представляющей состояние этого исполнения и его конечный результат. Поскольку они постоянны, они могут храниться, совместно использоваться, ссылаться, передаваться. Принимая во внимание, что в системе, управляемой исключительно событиями, вам не хватает истории, если вы начинаете слушать после факта, и вам (как правило) приходится слушать все события, слышать любые события. Обещание дает вам возможность инкапсулировать и подписаться на ограниченный одноцелевой поток событий, а также проверить состояние этого потока событий в любое время в будущем. – XML

+0

В целом, этот пост является отличным чтением принципов. Дополнительные сведения см. По адресу: https://www.oreilly.com/ideas/reactive-programming-vs-reactive-systems – XML

1

Для меня это похоже на сравнение апельсинов с яблоками. Давайте попробуем определить простым способом, что и что отличает вещи:

Реактивное программирование - это парадигма программирования, которая применяется, когда требуется достичь функциональности, сходной с привязкой данных в таких библиотеках, как KnockoutJS. Также примером могут служить формулы Excel: все ячейки похожи на переменные в памяти. Есть те, которые просто содержат некоторые данные и те, которые вычисляются из этих данных. Если первое изменяется, то и последнее. Обратите внимание, что парадигма касается реализации более низкого уровня; когда кто-то говорит о реактивном программировании, они ссылаются на данные, его изменения и то, что происходит, когда оно мутирует.

С другой стороны, управляемое событиями программирование касается архитектуры системы. Согласно этой парадигме события и обработчики событий являются основой системы, и все построено на них и вокруг них. Обычными примерами могут быть мультиплексирование пользовательского интерфейса и веб-сервера. Вы чувствуете, как все это по-другому? Парадигма применяется на уровне всей системы или подсистемы.

Как реактивное программирование связано с обещаниями? Я думаю, что обещания - это альтернатива управляемому событиями и обратному аду.

Promise - это инструмент для достижения параллелизма и конкретного порядка выполнения. Его можно использовать в любой парадигме.

На практике парадигмы служат различным целям и на разных уровнях. Вы можете иметь управляемый событиями дизайн с некоторыми битами реактивного кода. Вы можете иметь распределенную систему, которая использует реактивные шаблоны проектирования. Однако события, в конечном счете, являются концепцией более высокого уровня. Реакция - это данные и их переоценка, подход к реализации или ее детали, а события - это нечто, что естественно возникает из случая и управляет вашим дизайном.

0

Реактивное программирование - это все о потоках, это могут быть потоки событий или что-то еще. Он отправляет/анонсирует эти потоки или подписывается/просматривает эти потоки или потоковые преобразования, которые приводят к некоторым событиям. Таким образом, парадигмы программирования связаны между собой.