web-dev-qa-db-ja.com

リアクティブプログラミングは、イベント駆動型プログラミングとどのように異なりますか?

JavaScriptでリアクティブプログラミングと関数型リアクティブプログラミングを学んでいます。私は非常に混乱しています。

ウィキペディアによると、命令型、OORP、関数型など、リアクティブコードを記述する方法はさまざまです。イベントドリブンがリアクティブコードを記述するための別の方法であるかどうかを知りたいですか?

リアクティブプログラミングはPromiseにどのように関係していますか? promiseは、イベント駆動型のコールバック地獄に代わるものだと思います。

33
Narayan Prusty

リアクティブプログラミングはPromiseにどのように関係していますか?約束は、イベント駆動型のコールバック地獄の代替手段だと思います。

実際には、この2つは関連しています。Promisesを関数型リアクティブプログラミングのゲートウェイドラッグと呼びたいです。

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

Promiseは、1つのアイテムを持つEventStreamsと考えることができます。または、EventStreamsは、時間の経過とともに複数のPromiseと考えることができます。

プロミスは連鎖することができ、リアクティブプログラミングに近づいています:

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

両方のコードスニペットは同じことをしますが、思考には大きな違いがあります:約束を使用すると、明確な方法で非同期ステップで単一のアクションを処理することを考えています-思考は不可欠であり、ステップごとに物事をやっています。 FRPでは、「これらの2つの変換ステップを適用することにより、userIdsのストリームからユーザー名のストリームが作成されます」と言われます。ユーザー名のストリームがあり、それらがどこから来たのかを気にせずに、「新しいユーザー名があるときはいつでも、ユーザーに表示する」と言います。

FRPコーディングスタイルは、値のストリーム(つまり、時間の経過とともに変化する値)およびこれらの値間の関係として問題をモデル化するために役立ちます。 Promisesを既に知っている場合、最初の学習曲線は少し簡単になりますが、主な利点は、問題の考え方とモデリングを異なる方法で開始した場合にのみ得られます-FRPライブラリを使用した命令型プログラミングを実行することは可能です.

22
OlliM

リアクティブプログラミングはイベント駆動型プログラミングとどのように異なりますか?

イベント駆動プログラミングは、いわゆるイベントを中心に展開します。イベントは、何かが発生したときにプログラムが「起動」する抽象的なものです。コード内の他の場所はイベントを「リッスン」し、そのイベントが発生したときに必要なアクションで応答します。たとえば、イベントは「ユーザーがこのボタンを押した」または「プリンタでドキュメントの印刷が完了しました」などです。

リアクティブプログラミングはdataを扱います。最終的に、これはイベント駆動型プログラミングの特殊なケースです。イベント:データが変更されました。イベントハンドラー:さらにデータを変更します(該当する場合)。この概念は、通常、スプレッドシートについて考えるときに解消されます。 cell1 = cell2 + cell3を設定すると、cell2およびcell3のデータ変更イベントに2つのイベントハンドラーが暗黙的に設定され、cell1のデータが更新されます。 cell1のデータには、その値に依存するセルがないため、そのようなイベントハンドラはありません。


TL; DR;

ウィキペディアによると、命令型、OORP、関数型など、リアクティブコードを記述する方法はさまざまです。イベントドリブンがリアクティブコードを記述するための別の方法であるかどうかを知りたいですか?

イベント駆動型プログラミングの考え方は、命令型vs. OO vs. Functional。

  • Imperitive programming :プログラムの状態を変更することで、目的を達成できるようにします。ほとんどのコンピューターは( 宣言型プログラミング とは対照的に)命令型ですが、高レベルの言語は宣言型である場合があります。対照的に、宣言型プログラミングは、コードにどのように実行させるかではなく、何を実行するかを指定するコードの記述を扱います。
  • [〜#〜] o [〜#〜]bject[〜#〜] o [ 〜#〜]指向プログラミング :いわゆるオブジェクト、または関連するメソッドを持つデータのバッグを扱います。メソッドはオブジェクトに関連付けられたデータにアクセスできるため、関数型プログラミングとは異なります。
  • 関数型プログラミング :再利用可能な関数、または入力と出力を受け取るプロシージャを扱います。これは、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)

リアクティブプログラミングはPromiseにどのように関係していますか?

約束は、プログラム実行の流れの抽象化であり、次のように要約できます。

  • アスカー:自分がやっていることをやり終えたら、いつでも電話してくれませんか?
  • 回答者:確かに、私約束

ここで特別なことはありませんが、コードが実行される順序を考える別の方法です。たとえば、Promiseは、リモートマシンを呼び出すときに役立ちます。約束があれば、「このリモートコールから戻ったときに折り返し電話してください」と言うことができます。どちらのライブラリを使用する場合でも、promisesがリモートマシンから何かを取得したときにコールバックします。多くの場合、これは、呼び出しが戻るのを待たずにその間に何か他のことを行うことができるので便利です。

パンチライン:さまざまなスタイルのコードがありますが、イベントドリブンおよびリアクティブプログラミングのパターンではあまり大きな役割を果たしません。私の知る限り、ほとんどの言語でイベント駆動型またはリアクティブ型プログラミングを行うことができます。

68
Frank Bryce

リアクティブプログラミングはすべてストリームに関するものであり、イベントのストリームなど、あらゆるものが考えられます。これらのストリームの発行/発表、またはこれらのストリームのサブスクライブ/視聴、またはいくつかのイベントにつながるストリーム変換についてです。したがって、両方のプログラミングパラダイムは関連しています。

0
kg11

私にとっては、オレンジとリンゴを比較するようなものです。何が何であるかを簡単に定義して、物事を区別してみましょう:

リアクティブプログラミングは、KnockoutJSのようなライブラリのデータバインディングに似た機能を実現したいときに適用されるプログラミングパラダイムです。また、Excelの数式も例になります。すべてのセルはメモリ内の変数のようなものです。単にいくつかのデータを保持するものと、そのデータから計算されるものがあります。前者が変わると、後者も変わります。パラダイムは低レベルの実装に関するものであることに注意してください。誰かがリアクティブプログラミングについて話しているとき、彼らはデータ、その変化、そしてそれが変化したときに何が起こるかを指している。

一方、イベント駆動型プログラミングはシステムアーキテクチャに関するものです。そのパラダイムによると、イベントとイベントハンドラーはシステムの基礎であり、すべてがその上および周囲に構築されます。一般的な例は、UIおよびWebサーバーの多重化です。これがすべて違うと感じますか?パラダイムは、システム全体またはサブシステムのレベルで適用されます。

リアクティブプログラミングはPromiseにどのように関係していますか? promiseは、イベント駆動型のコールバック地獄に代わるものだと思います。

Promiseは、並行性と特定の実行順序を実現するツールです。任意のパラダイムで使用できます。

実際には、パラダイムはさまざまな目的とさまざまなレベルで機能します。いくつかのリアクティブコードを使用して、イベントドリブンデザインを作成できます。リアクティブデザインパターンを使用する分散システムを使用できます。ただし、イベントは最終的には上位概念です。リアクティブとは、データとその再評価、実装のアプローチまたはその詳細に関するものであり、イベントはケースから自然に発生し、設計を推進するものです。

0
Orif Khodjaev