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

Я изучаю реактивное программирование и функциональное реактивное программирование на JavaScript. Я в полном замешательстве.

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

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

4 ответов


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

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

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

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

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

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

то же самое с беконом.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 поможет вам моделировать вашу проблему как поток значений (т. е. значений, которые меняются со временем) и отношений между этими значениями. Если вы уже знаете обещания, то начальная кривая обучения будет немного проще, но основное преимущество получается только тогда, когда вы начинаете думать и моделировать проблему по-другому - это возможно (если не очень полезно) для императивного программирования с библиотеками FRP.


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

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

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


TL; DR;

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

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

  • Imperitive программирования: фокусируется на изменение состояния вашей программы позволит достичь желаемого. Большинство компьютеров являются императивными (в отличие от декларативное Программирование), тогда как языки более высокого уровня иногда декларативной. Декларативное Программирование, напротив, имеет дело с написанием кода, который определяет, что вы хотите, чтобы он делал, а не как вы хотите, чтобы код это делал.
  • Object Oriented programming: общается с так называемыми предметами, или мешками данные со связанными методами. Отличается от функционального программирования тем, что методы имеют доступ к данным, связанным с объектами.
  • функциональное программирование: общается с повторно используемыми функциями, или процедурами которые принимают входные сигналы и выходы. Это отличается от программирования 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)

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

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

  • Аскер: когда закончишь делать то, что делаешь, перезвонишь мне?
  • ответчик: конечно, я обещание

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

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


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

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

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

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

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

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


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