Node.jsでイベントを正しい方法で使用する方法

イベント駆動型プログラミングが普及する前は、アプリケーションのさまざまな部分間で通信する標準的な方法は非常に簡単でした。別のコンポーネントにメッセージを送信するコンポーネントは、そのコンポーネントのメソッドを明示的に呼び出していました。ただし、イベント駆動型のコードは、呼び出されるのではなく反応するように記述されています。

イベンティングの利点

このアプローチにより、コンポーネントはさらに分離されます。アプリケーションの作成を続けると、途中でイベントを識別します。適切なタイミングでそれらを起動し、それぞれに1つ以上のイベントリスナーをアタッチします。機能の拡張がはるかに簡単になります。特定のイベントにリスナーを追加できます。既存のリスナーや、イベントが発生したアプリケーションの一部を改ざんしていません。私たちが話しているのは、Observerパターンです。

https://www.dofactory.com/javascript/observer-design-pattern

イベント駆動型アーキテクチャの設計

イベントを識別することは非常に重要です。システムから既存のイベントを削除/置換する必要がなくなります。これにより、イベントにアタッチされた任意の数のリスナーを削除/変更することが強制される場合があります。私が使用する一般的な原則は、ビジネスロジックのユニットが実行を終了したときにのみイベントの発生を考慮することです。

そのため、ユーザーの登録後にさまざまなメールを送信したいとします。現在、登録プロセス自体には、多くの複雑な手順とクエリが含まれる場合があります。しかし、ビジネスの観点からは、これは一歩です。また、送信される各電子メールも個別の手順です。そのため、登録が完了したらすぐにイベントを発生させるのが理にかなっています。複数のリスナーが接続されており、それぞれが1種類のメールを送信します。

Nodeの非同期のイベント駆動型アーキテクチャには、「エミッタ」と呼ばれる特定の種類のオブジェクトがあります。これらは、「リスナー」と呼ばれる機能を呼び出す名前付きイベントを発行します。イベントを発行するすべてのオブジェクトは、EventEmitterクラスのインスタンスです。それを使用して、独自のイベントを作成できます。

組み込みのイベントモジュール(詳細を確認することをお勧めします)を使用して、EventEmitterにアクセスします。

これは、サーバーがHTTPリクエストを受信し、新しいユーザーを保存してイベントを発行するアプリケーションの一部です。

そして、リスナーをアタッチする別のモジュール:

ポリシーを実装から分離することをお勧めします。この場合、ポリシーとは、どのリスナーがどのイベントをサブスクライブするかを意味します。実装とは、リスナー自体を意味します。

この分離により、リスナーも再利用可能になります。同じメッセージ(ユーザーオブジェクト)を送信する他のイベントに添付できます。また、1つのイベントに複数のリスナーが接続されている場合、それらは同期して、接続された順序で実行されることに注意することも重要です。したがって、sendEmailOnRegistrationの実行が完了した後にsomeOtherListenerが実行されます。

ただし、リスナーを非同期で実行する場合は、次のようにsetImmediateで実装をラップするだけです。

リスナーを清潔に保つ

リスナーを作成するときは、単一​​の責任原則に固執します。 1人のリスナーは1つのことだけを行い、それをうまく行う必要があります。たとえば、リスナーによって、イベントによって送信されたデータ(メッセージ)に応じて何をするかを決定する条件を書きすぎないようにしてください。その場合、異なるイベントを使用する方がはるかに適切です。

必要なときにリスナーを明示的に切り離す

前の例では、リスナーは完全に独立した関数でした。ただし、リスナーがオブジェクト(メソッド)に関連付けられている場合、サブスクライブしていたイベントから手動で切り離す必要があります。そうしないと、オブジェクトの一部(リスナー)が外部オブジェクト(エミッター)によって引き続き参照されるため、オブジェクトはガベージコレクションされません。したがって、メモリリークの可能性。

たとえば、チャットアプリケーションを作成していて、ユーザーが接続しているチャットルームに新しいメッセージが到着したときに通知を表示する責任が必要な場合は、そのユーザーオブジェクト自体に含める必要があります。

ユーザーがタブを閉じたり、インターネット接続をしばらく失ったりした場合、当然、サーバー側でコールバックを実行して、そのうちの1人がオフラインになったことを他のユーザーに通知することができます。もちろん、この時点では、オフラインユーザーに対してdisplayNewMessageNotificationを呼び出すことは意味がありません。明示的に削除しない限り、新しいメッセージで引き続き呼び出されます。そうしないと、不必要な呼び出しは別として、ユーザーオブジェクトも無期限にメモリに残ります。そのため、ユーザーがオフラインになるたびに実行されるサーバー側コールバックでdisconnectFromChatroomを呼び出してください。

気をつけて

イベント駆動型アーキテクチャの疎結合は、注意しないと複雑さを増す可能性もあります。システムの依存関係を追跡するのは難しい場合があります。リスナー内からイベントの発行を開始すると、アプリケーションでこの問題が特に発生しやすくなります。これにより、予期しないイベントのチェーンがトリガーされる可能性があります。