Node.jsのeventemitterとそのデザインパターンについてまとめてみた

# はじめに
この記事ではeventEmitterとeventEmitterに関わるデザインパターンについて紹介しています。
evenEmitterをマスターすることで、よりプロのプログラマー（略してプロプロ）になれると思います。

# eventemitterとは
まずイベントエミッターとはなにか説明します。
これ、独自にイベントを作成し、指定したタイミングに関数を発火することができます
イベント駆動開発でよく用いられます。

イメージで言うと、フロントエンドでいうと、ボタンを押したときにonpushに登録された関数が発火しますよね。それです！
eventemitterを用いると、自作でイベントを作って、好きなタイミングで発火することができるようになります。
Node.jsではeventemitterがストリームの裏側で作られ、実行されています。

# EventEmitterの実行例
```js
const EventEmitter = require("events")
const eventEmitter = new EventEmitter()

const bakuhatsu=() => { console.log("ドッカーーーン") }

eventEmitter.on("爆発",bakuhatsu)
eventEmitter.once("爆発", () => {
  console.log("一回だけドッカーーーン")
})
eventEmitter.emit("爆発")
//ドッカーーーン
//一回だけドッカーーーン

eventEmitter.emit("爆発")
//ドッカーーーン

console.log("爆発解除")
eventEmitter.off("爆発",bakuhatsu)
eventEmitter.emit("爆発")
//(何もなし)

```
# EventEmitter の主要なインスタンスメソッド
最初に簡単に用法をまとめておきます。

1. `on(イベント名、関数名)`でイベントを登録し、
2. `emit(イベント名)`でイベントに指定した関数を実行！
3. `off(イベント,関数名)`でイベントに登録した関数の削除

## on(event,listener)
指定したイベントに新しいリスナを登録します。
（第一引数に文字列　イベントの名前（任意）
　第二引数にコールバック関数　第一引数に登録したイベントが呼ばれたときに発火する）

```js:例
eventEmitter.on("爆発",()=>{console.log("ドッカーーーン")})
```

## once(event,listener)
指定したイベントに新しいリスナを登録します。
（第一引数に文字列　イベントの名前（任意）
　第二引数にコールバック関数　第一引数に登録したイベントが呼ばれたときに発火する）
これはon()メソッドと同様です。
このリスナは、イベントが一回発行されるとリスナが削除されます。なので、そのイベントの最初の一回しか第二引数に登録したコールバック関数が実行されません。

```js:例
eventEmitter.once("爆発",()=>{console.log("一回だけドッカーーーン")})
```

## off(event,listener)
on()メソッドで登録したイベントの特定のリスナを削除します。
（第一引数に文字列　イベントの名前（任意）
　第二引数にコールバック関数　on()メソッドで登録した第二引数）

```js:例
eventEmitter.off("爆発",()=>{console.log("ドッカーーーン")})
```

## emit(event,[...args])
on()やonce()メソッドで追加したイベントを発火します。
（第一引数に文字列　イベントの名前（任意）
　第二引数には引数　on()やonce()で登録したコールバック関数に引数が必要な場合のみ使用する）

```js:例
eventEmitter.emit("爆発")    //今回は引数なし
```

使い方は、以上です

ここからは、eventemitterを利用するデザインパターンについて説明していきます。
まずかんたんにデザインパターンについて説明しておきます。
# デザインパターンとは
オブジェクト指向言語で使われる設計パターンのことです。オブジェクト指向では再利用性の高いクラスが必須です。
ではどのような方向性で設計していけばよいのか。。。。
それを示してくれるのがデザインパターンです。

代表的なデザインパターンは23種類あります。(今回は詳しく説明しない）


ここではeventemitterで用いられるObserverパターンについて解説していきます。

# Observerパターンについて
ObserverパターンはNode.js以外でもよく用いられる代表的なデザインパターンです。英語のObserverとは、観察者や監視役という意味があります。
このパターンでは、監視対象に対して発生した何らかのイベントが、監視役(Observer)に逐一通知されます。
監視役(Observer)はあらかじめ監視対象に対して監視を行うための登録処理を行い、監視対象はイベントの発生タイミングで登録済みの監視役（Observer)に対して通知処理を実行します。

それぞれのSubjectには複数のObserverを登録できます。

簡単な例を上げて説明します。
中学校を想定します。ここでは、一人の生徒が監視対象です。先生は一人の生徒「たかひろ」くんに対してそれぞれの処理を仕込みます。
それぞれの先生は、自分の専門の処理を「たかひろ」くんに仕込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1369844/e36fd84d-dcf6-172b-71b5-c5e19be95e47.png)


そして「たかひろ」くんは登録された処理に従って、
数学の勉強がわからないときは数学の先生に、
野球の打撃の成績が悪いときは、筋肉の先生に、（「たかひろ」くんは野球部）
熱があって、吐き気もするときは、保健室の先生に、
通知を出します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1369844/23e61f98-6024-066b-6e71-14168550b9d1.png)

ここまでがObserverパターンです。
先生が生徒に処理を仕込み、生徒が通知を出すところまででひとくくりです。

ここでこの例に従ってeventemitterのコードを書いてみます。

```js
const EventEmitter = require("events")
const eventEmitter = new EventEmitter()

const helpme=(teacher)=>{
  console.log(teacher+"、助けてください")
}
eventEmitter.on("数学がわからない", helpme)
eventEmitter.on("最近打率が悪い", helpme)
eventEmitter.on("体調が悪い", helpme)

//　先生(Observer)によってイベントが仕込まれる
class takahiro {
  static suugaku_nervous() {
    eventEmitter.emit("数学がわからない","数学得意な先生")
  }
  static sports_nervous() {
    eventEmitter.emit("最近打率が悪い","筋肉ムキムキな先生")
  }
  static condition_nervous() {
    eventEmitter.emit("体調が悪い","保健室の先生")
  }
}

//「たかひろ」くんが先生にイベントを通知する
takahiro.suugaku_nervous()

//***実行結果***
//数学得意な先生、助けて！
```

デザインパターンとeventemitterの話はここまでです。

# 実際のコード
最後に実際に使われているコードの紹介をしておきます。

```js
const http = require("http")
var fs = require("fs")
//serverのeventEmitterを作成
const server = http.createServer()

//requestというイベントに関数を仕込む
//serverにアクセスがあったときに発火する
server.on("request", (req, res) => {
  fs.readFile("./helloWorld.html", "utf-8", function (error, data) {
    res.writeHead(200, { "Content-Type": "text/html" })
    res.write("requestに登録されたイベント発火")
    res.write(data)
    res.end()
  })
})

//listeningというイベントに関数を仕込む
//これはserver.listen(8000)したときに発火する
server.on("listening", (res, req) => {})

//errorというイベントに関数を仕込む
//エラーが起こったときに発火する
server.on("error", err =>{
  console.error(err);
})

//closeというイベントに関数を仕込む
//これはserver.close()したときに発火する(ここではserver.close()はこめんとあうとした）
server.on("close", () => {})

server.listen(8000)
// server.close()
```

```html:helloEarth.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>Hello,Earth! And,Hello universe!</h1>
</body>
</html>
```
localhost:8000にアクセスした結果
----
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1369844/295ad7d9-68b9-62c5-bb72-a2667a7cde0c.png)

何気なくhttpモジュールで使っていた関数にもeventEmitterが仕込まれていました。自分が使っている関数や処理がeventEmitterのものかどうか見極める事ができれば、プログラミングのレベルもぐんぐん上がっていくと思いますｌ

# 最後に
Streamの記事を書くつもりがいつマニカeventEmitter の記事を書いていました。
次回はStreamの記事を書きます！！

おいらの記事を最後まで見てくれてありがとうございました。