Language: EN

eventos-en-javascript

Events in JavaScript

In JavaScript, an event is simply an indication that something has occurred. This allows our code to respond dynamically to various situations. For example:

  • A user presses a key.
  • A timer ends.
  • A signal is received from an API.

Events are a simple mechanism for asynchronous programming, as they allow us to manage tasks in a non-blocking way.

Event management is slightly different depending on whether it is done in a browser or in a runtime like Node.js.

The concepts are the same, but the syntax is somewhat different. We will see this in the article.

Event handler functions

An event handler function is a function that is executed when an event occurs.

For it to work, we need to associate an event handler function with an event emitter.

To do this, we use the method:

  • In the browser addEventListener
  • In Node.js on
// Bind a handler with `addEventListener`
myEmitter.addEventListener("myEvent", (event) => {
  console.log("Handling the event:", event);
});

How to trigger an event in JavaScript

Triggering an event, also known as emitting an event, involves creating an instance of the event and firing it on a specific object.

JavaScript provides several ways to do this. The most common method to trigger events in JavaScript is

  • In the browser, dispatchEvent.
  • In Node.js, emit.
// Create a standard event
let event = new Event("myEvent");

// Fire the event
document.dispatchEvent(event);

In this example:

  1. We create an event called myEvent.
  2. We use dispatchEvent to trigger it, thus activating the associated handler.

Basic example

Let’s see how to combine event emission with the handler function, with some complete examples.

In the browser

In the browser, events are fundamental for interacting with the user interface. For example, you can listen for events like click, submit, or keydown on HTML elements and react to them.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Events in the Browser</title>
</head>
<body>
  <button id="myButton">Click here</button>
  <script>
    // Select the button
    let button = document.getElementById("myButton");

    // Add a handler for the 'click' event
    button.addEventListener("click", () => {
      console.log("The button was clicked");
    });
  </script>
</body>
</html>

In this example:

  • The click event is used to detect when the user clicks on a button.

Using events in Node.js

Node.js includes the events module, which provides the EventEmitter class, allowing you to register handlers and emit events.

import { EventEmitter } from "events";

// Class that simulates being a server
class Server extends EventEmitter {
  start() {
    console.log("Server started");
    this.emit("serverStarted"); // emits an event on start
  }
}

// Create an instance of the server
const server = new Server();

// Register handler for the event
server.on("serverStarted", () => {
  console.log("The server is ready to receive requests");
});

// Simulate server execution
server.start();

Here:

  1. We create an event emitter with EventEmitter.
  2. We register a handler for the myEvent event using on.
  3. We use the emit method to trigger the event and pass a message as an argument.

Defining custom events

In addition to handling predefined events, we can create custom events. This is useful in complex projects because we can provide more information than with generic events.

To create our own events, we can use the Event or CustomEvent classes.

Event

Event is a very simple class that allows us to add a message (optional) to identify the event.

// Create a custom event
let customEvent = new Event("myEvent");

// Fire the event
document.dispatchEvent(customEvent);

CustomEvent

CustomEvent extends the capabilities of the standard event, allowing you to pass additional data when emitting the event.

// Create a custom event with additional data
let customEvent = new CustomEvent("myCustomEvent", {
  detail: { message: "Hello from a custom event" },
});

// Assign a handler to receive the data
document.addEventListener("myCustomEvent", (e) => {
  console.log(e.detail.message); // Access the custom data
});

// Fire the event
document.dispatchEvent(customEvent);

In this case, we use the detail property to include additional information that handlers can process.

Integrating events with promises

Sometimes, you may want to integrate event handling with Promises. This is useful for synchronizing asynchronous tasks.

function waitForEvent(event) {
  return new Promise((resolve) => {
    document.addEventListener(event, resolve, { once: true });
  });
}

async function main() {
  console.log("Waiting for event...");
  await waitForEvent("myEvent");
  console.log("Event received.");
}

// Execute and simulate the event
main();
document.dispatchEvent(new Event("myEvent"));

Here, the waitForEvent function converts an event into a Promise, which allows waiting for its resolution within an asynchronous function.

Internal workings

Under the hood, JavaScript is a single-threaded execution language, which means that it can only execute one task at a time.

When an event occurs, the main flow of the program is not interrupted. Instead, the action associated with the event is registered in the event queue.

The event loop takes care of processing the tasks in this queue when the main thread is free.