JavaScriptでリアクティブプログラミングと関数型リアクティブプログラミングを学んでいます。私は非常に混乱しています。
ウィキペディアによると、命令型、OORP、関数型など、リアクティブコードを記述する方法はさまざまです。イベントドリブンがリアクティブコードを記述するための別の方法であるかどうかを知りたいですか?
リアクティブプログラミングはPromiseにどのように関係していますか? promiseは、イベント駆動型のコールバック地獄に代わるものだと思います。
リアクティブプログラミングは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ライブラリを使用した命令型プログラミングを実行することは可能です.
リアクティブプログラミングはイベント駆動型プログラミングとどのように異なりますか?
イベント駆動プログラミングは、いわゆるイベントを中心に展開します。イベントは、何かが発生したときにプログラムが「起動」する抽象的なものです。コード内の他の場所はイベントを「リッスン」し、そのイベントが発生したときに必要なアクションで応答します。たとえば、イベントは「ユーザーがこのボタンを押した」または「プリンタでドキュメントの印刷が完了しました」などです。
リアクティブプログラミングはdataを扱います。最終的に、これはイベント駆動型プログラミングの特殊なケースです。イベント:データが変更されました。イベントハンドラー:さらにデータを変更します(該当する場合)。この概念は、通常、スプレッドシートについて考えるときに解消されます。 cell1 = cell2 + cell3
を設定すると、cell2
およびcell3
のデータ変更イベントに2つのイベントハンドラーが暗黙的に設定され、cell1
のデータが更新されます。 cell1
のデータには、その値に依存するセルがないため、そのようなイベントハンドラはありません。
TL; DR;
ウィキペディアによると、命令型、OORP、関数型など、リアクティブコードを記述する方法はさまざまです。イベントドリブンがリアクティブコードを記述するための別の方法であるかどうかを知りたいですか?
イベント駆動型プログラミングの考え方は、命令型vs. OO vs. Functional。
イベント駆動型プログラミング :プログラムで発生する他の何か(「イベント」)を処理(「ハンドル」)するために、プログラムを構築します。言い換えれば、それはあなたのコードをこのように論理的に構造化します
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がリモートマシンから何かを取得したときにコールバックします。多くの場合、これは、呼び出しが戻るのを待たずにその間に何か他のことを行うことができるので便利です。
パンチライン:さまざまなスタイルのコードがありますが、イベントドリブンおよびリアクティブプログラミングのパターンではあまり大きな役割を果たしません。私の知る限り、ほとんどの言語でイベント駆動型またはリアクティブ型プログラミングを行うことができます。
リアクティブプログラミングはすべてストリームに関するものであり、イベントのストリームなど、あらゆるものが考えられます。これらのストリームの発行/発表、またはこれらのストリームのサブスクライブ/視聴、またはいくつかのイベントにつながるストリーム変換についてです。したがって、両方のプログラミングパラダイムは関連しています。
私にとっては、オレンジとリンゴを比較するようなものです。何が何であるかを簡単に定義して、物事を区別してみましょう:
リアクティブプログラミングは、KnockoutJSのようなライブラリのデータバインディングに似た機能を実現したいときに適用されるプログラミングパラダイムです。また、Excelの数式も例になります。すべてのセルはメモリ内の変数のようなものです。単にいくつかのデータを保持するものと、そのデータから計算されるものがあります。前者が変わると、後者も変わります。パラダイムは低レベルの実装に関するものであることに注意してください。誰かがリアクティブプログラミングについて話しているとき、彼らはデータ、その変化、そしてそれが変化したときに何が起こるかを指している。
一方、イベント駆動型プログラミングはシステムアーキテクチャに関するものです。そのパラダイムによると、イベントとイベントハンドラーはシステムの基礎であり、すべてがその上および周囲に構築されます。一般的な例は、UIおよびWebサーバーの多重化です。これがすべて違うと感じますか?パラダイムは、システム全体またはサブシステムのレベルで適用されます。
リアクティブプログラミングはPromiseにどのように関係していますか? promiseは、イベント駆動型のコールバック地獄に代わるものだと思います。
Promiseは、並行性と特定の実行順序を実現するツールです。任意のパラダイムで使用できます。
実際には、パラダイムはさまざまな目的とさまざまなレベルで機能します。いくつかのリアクティブコードを使用して、イベントドリブンデザインを作成できます。リアクティブデザインパターンを使用する分散システムを使用できます。ただし、イベントは最終的には上位概念です。リアクティブとは、データとその再評価、実装のアプローチまたはその詳細に関するものであり、イベントはケースから自然に発生し、設計を推進するものです。