What does it mean “event-driven” in JavaScript and Node.js?
Tags: javascript, beginners, node
Published: 2019-12-30 09:48:26

---
title: "What does it mean “event-driven” in JavaScript and Node.js?"
published: true
description: "Just starting out with JavaScript and event-driven is all over the place? Worry not and keep reading to learn more!"
tags: javascript, beginners, nodejs
canonical_url: https://www.valentinog.com/blog/event/
---

_Just starting out with JavaScript and "event-driven" is all over the place? Worry not and keep reading to learn more!_

## Event-driven and publish-subscribe

**Event-driven** architectures build on a common pattern in software development known as **publish-subscribe** or **observer** pattern.

In an **event-driven** architecture there are at least **two actors**: the **subject** and the **observer**.

The **subject is like an FM radio**, it **broadcasts** a **message to any observer** interested in listening what the subject says.

![Observer pattern](https://www.valentinog.com/blog/wp-content/uploads/2019/12/observer-pattern.gif)

There could be just one or one hundred observers, it does not matter as long as the subject has some message to broadcast.

Keep in mind that event-driven, publish-subscribe, and observer pattern are not the same thing in practice, but ideally they use the same approach: an entity broadcasts a message and other entities listen for it.

The publish-subscribe pattern is old as me. It's been theorized around 1987, while the observer pattern appeared in the quintessential book "Design patterns" by the gang of four in 1994.

## How does event-driven applies to JavaScript in the browser?

**JavaScript runs in your browser thanks to an engine**. 

Most popular JavaScript engines are V8, used by Google Chrome and Node.js, SpiderMonkey for Firefox, and JavaScriptCore, used by Safari/WebKit.

**JavaScript engines enhance the language by providing a rich environment**, offering also an **event-driven platform for JavaScript**.

In practice, JavaScript in the browser can interact with HTML elements, which are **event emitters**, that is, **subjects able to emit events**.

Consider this trivial example, an HTML document with a button:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>What means "event-driven" in JavaScript?</title>
</head>
<body>
<div>
    <button id="subscribe">SUBSCRIBE</button>
</div>
</body>
</html>
```

Without JavaScript the button is inanimate. Now, HTML buttons are elements of type HTMLButtonElement, and as with any HTML element they're connected to **EventTarget**, the common ancestor of every HTML element.

Event targets in the browser are objects capable of **emitting events**: they're **subjects** in the observer pattern.

A bit confusing? Remember: a subject is the FM radio, so any HTML elements is like a broadcaster.

In a moment you'll see who the **observers** are.

## Subject and observer in the browser

If HTML elements are **subjects**, who are the **observers**? Any JavaScript **function registered as a listener** can react to events in the browser.

Select an HTML element with JavaScript:

```javascript
const btn = document.getElementById('subscribe');
```

and **register a listener with addEventListener**:

```javascript
const btn = document.getElementById('subscribe');

btn.addEventListener("click", function () {
    console.log("Button clicked");
});
```

Here "click" is the event, **button is the subject**, or the emitter, and the **function is a listener, or the observer**.

To recap:

**HTML elements** are **event emitters**.

JavaScript **functions registered as listeners are the observers**.

All these components make **an event-driven architecture**. To try the code save this HTML file (or try it on Codepen), click the button and check out the browser's console:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>What means "event-driven" in JavaScript?</title>
</head>
<body>
<div>
    <button id="subscribe">SUBSCRIBE</button>
</div>
</body>
<script>
    const btn = document.getElementById('subscribe');
    btn.addEventListener("click", function () {
        console.log("Button clicked");
    });
</script>
</html>
```

In the next section you'll see the same concepts, applied to Node.js.

## How does event-driven applies to Node.js?

**Node.js** is an environment for running JavaScript outside of the browser (command line tools and server side) based on the V8 engine.

Much of what you do in Node.js is based on **events**. There is always an **emitter object** and some observers listening for messages.

In Node.js there isn't any HTML element so **most events originate from processes, interactions with networks, files**, and so on.

Every event emitter in Node.js has a method named **on** which takes at least two arguments:

- the name of the event to listen to
- a listener function

Let's make a practical example. Consider this simple Node.js server:

```javascript
const net = require("net");

const server = net.createServer().listen(8081, "127.0.0.1");

server.on("listening", function () {
  console.log("Server listening!");
});

server.on("connection", function (socket) {
  console.log("Client connected!");
  socket.end("Hello client!");
});
```

Here we create a server listening on port 8081, localhost. On the **server object we call the on method** for registering two listeners function.

The **listening** event is fired as soon as the server starts, while the **connection event** fires when a client connects to 127.0.0.1:8081 (give it a shot!).

In this example **server** is the event emitter, the subject. Listeners functions on the other hand are **observers**. 

But where those **on** methods come from?

## Getting to know the EventEmitter

Any event-driven module in Node.js extends a root class named **EventEmitter**. In our previous example **createServer** from the **net module** uses EventEmitter under the hood.

**EventEmitter** in Node.js has two fundamental methods: **on** and **emit**.

If you want to draw a parallel with the browser you can think of EventEmitter as of any HTML element able to emit events.

To listen for events in the browser you call addEventListener on the subject object:

```javascript
const btn = document.getElementById('subscribe');

btn.addEventListener("click", function () {
    console.log("Button clicked");
});
```

In Node.js instead there is **on**:

```javascript
// omit

server.on("listening", () => {
  console.log("Server listening!");
});

// omit
```

To be precise there is also an **addListener** method on EventEmitter. **on** is an alias for it. 

**EventEmitter** has also an **emit** method, useful when you want to broadcast a custom event (a message).

If you want to play with EventEmitter import it from the "events" module and try to emit an event:

```javascript
const EventEmitter = require("events");

const emitter = new EventEmitter();

emitter.on("customEvent", () => console.log("Got event!"));

emitter.emit("customEvent");
```

Run the code with Node.js and you'll see "Got event" in the console.

## Other examples of observer / publish-subscribe in JavaScript

JavaScript does not have native support for observables, but there's a proposal for adding them to the language.

[RxJS](http://reactivex.io/) is a library which brings the observer pattern to JavaScript.

[Redux](https://www.valentinog.com/blog/redux/) is an implementation of the publish-subscribe pattern in JavaScript. "It is a glorified" **event emitter** where state changes are dispatched to any observer who listens.

Modern browsers are shipping with the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API), another example of observer pattern in action.

## Conclusion

I hope you learned something new from this post. You learned a lot of technical jargon, but in the end all boils down to a pattern invented roughly 30 years ago: **publish-subscribe**.

This pattern, also known as **observer**, is the basis for **event-driven architectures** we use today in **JavaScript and Node.js**.

Bears repeating that event-driven, publish-subscribe, and observer are not exactly the same thing: **event-driven architectures build on publish-subscribe**, and the observer pattern is more richer than DOM and Node.js events.

But in the end they're all part of the same family.

Thanks for reading and stay tuned!

[Originally published on my blog](https://www.valentinog.com/blog/event/)