"Promises" in JavaScript are one of those concepts that can seem intimidating at first, but once you understand them, they become an essential tool in your development toolbox. Especially in the world of web development, asynchronous operations are the norm, not the exception. From making network requests to processing large files, promises help handle time-consuming tasks without blocking the main flow of your code execution.
Table of Contents
ToggleWhat is a Promise in JavaScript?
A promise is an object that represents the eventual completion or failure of an asynchronous operation. Essentially, it's like saying "I promise to return some data to you in the future," and that promise can be kept (resolved) or broken (rejected).
Each promise in JavaScript has three possible states:
- Earring: The initial state, neither fulfilled nor rejected.
- Accomplished: It means that the operation was completed successfully.
- Rejected: It means the operation failed.
Creating a Promise
To create a promise, you use the constructor Promise
. This constructor takes an executor function which in turn accepts two arguments, resolve
y reject
, which are functions you can call to resolve or reject the promise, respectively.
Basic Example of a Promise
letDataPromise = new Promise((resolve, reject) => { // We simulate an asynchronous operation with setTimeout setTimeout(() => { if (/* success condition */) { resolve("Data received successfully!") ; } else { reject("Error receiving data."); } }, 2000);
In this example, after 2 seconds, the promise is resolved or rejected based on a condition. Although a simple example is used here, in practice you could be making an API call or reading a file from the file system.
Managing Promises with then
y catch
Once you have a promise, the next step is to know what to do with the result when the promise is resolved or rejected. Methods then()
y catch()
They provide a way to manage these two possible outcomes.
DataPromise .then((data) => { console.log(data); // "Data received successfully!" }) .catch((error) => { console.error(error); // "Error receiving the data." });
Chain Promises
Promises can be chained, meaning you can perform several asynchronous operations in sequence, each one starting when the previous one has finished.
fetch('https://api.example.com/data') .then(response => response.json()) // convert the response to JSON .then(json => { console.log("Data processed :", json); return json; // you can return data for the next then }) .catch(error => console.error("Error processing the request:", error));
Advanced Patterns
async
y await
ES2017 introduced two new keywords to simplify working with promises: async
y await
. The functions async
transform a function so that it returns a promise, and await
can be used to "pause" the execution of the function until the promise is resolved or rejected, greatly simplifying the handling of asynchrony.
async function getData() { try { let response = await fetch('https://api.example.com/data'); let json = await response.json(); console.log("Data received:", json); } catch (error) { console.error("Could not get data:", error); } }
Good practices
- Always handle rejected promises: Ignoring errors can lead to hours of debugging.
- Avoid 'Hell of Promises': Don't nest promises, use chaining or
async/await
. - Wear
Promise.all
to parallelize: If you have multiple promises that can be executed at the same time,Promise.all
It is a great tool.
If you want to continue learning and delving deeper into the promises and other advanced concepts of web development, or if you have any specific questions, feel free to visit and contact me through my blog or directly from this link. I would love to help you continue growing in your web development career.