In this blog, I will provide some Examples of Using Promises in ES6.
Promises in JavaScript, introduced with ECMAScript 6 (ES6), are a powerful tool for managing asynchronous operations. They offer a cleaner and more readable alternative to traditional callback-based approaches, addressing the challenges of callback hell and improving code maintainability. Promises simplify asynchronous code by providing a standardized way to handle success and error conditions, allowing developers to write more organized and modular code. With their inherent ability to chain and sequence asynchronous tasks, promises facilitate the creation of more scalable and comprehensible code structures. Additionally, features like Promise.all()
and Promise.race()
provide efficient ways to handle multiple asynchronous operations concurrently. By promoting a more intuitive and structured approach to asynchronous programming, promises contribute to a more robust and maintainable codebase in JavaScript applications.
Basic Examples of Using Promises in ES6
const simplePromise = new Promise((resolve) => {
setTimeout(() => {
resolve('Promise resolved after 2 seconds');
}, 2000);
});
simplePromise.then((result) => console.log(result));
Output
new Promise((resolve) => {…})
- The Promise constructor takes a function as its argument, commonly referred to as the executor function. This function receives two parameters: resolve and reject. In this case, it only uses resolve.
resolve(‘Promise resolved after 2 seconds’)
- The resolve function is provided by the Promise constructor. When called, it fulfills the promise with the specified value. In this example, it fulfills the promise with the string ‘Promise resolved after 2 seconds’.
simplePromise.then((result) => console.log(result))
- The then method is used to handle the resolved value of the promise. It takes a callback function as its argument, and this callback is executed when the promise is successfully resolved.
- In this case, when the promise is resolved after 2 seconds, the callback function (result) => console.log(result) is executed, which logs the resolved value to the console.
So, resolve is used to fulfill the promise with a specified value, and then is used to handle the resolved value of the promise and execute a callback function when the promise is successfully resolved.
Promise Chaining
const promiseChain = new Promise((resolve) => {
resolve(1);
});
promiseChain
.then((result) => result * 2)
.then((result) => result * 3)
.then((result) => console.log(result));
Output
The key idea here is that each then returns a new promise, and the value returned or resolved by the previous then becomes the input for the next one in the chain. This allows for a sequential execution of asynchronous operations, making the code more readable and maintainable. In this specific example, the final result is 1 * 2 * 3, which is 6.
More Examples of Using Promises in ES6 on Fetching Data from API
Fetch API with Promises
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
Output
fetch(‘https://jsonplaceholder.typicode.com/todos/1’)
- The fetch function is a built-in JavaScript function that initiates a network request to the specified URL. In this case, it’s making a GET request to retrieve information about a todo with ID 1 from the JSONPlaceholder API.
.then(response => response.json())
- The then method is used to handle the response from the server. It takes a callback function that receives the response object.
- response.json() is called to parse the response body as JSON. This returns a promise that resolves with the parsed JSON data.
.then(data => console.log(data))
- Another then method is used to handle the parsed JSON data. It takes a callback function that receives the parsed data as its argument.
- In this case, the callback logs the parsed data to the console.
.catch(error => console.error(‘Error:’, error))
- The catch method is used to handle errors that might occur during the fetch operation. If any error occurs at any point in the promise chain, it will be caught by this catch block.
- The callback function logs an error message to the console.
This code is a basic example of making an asynchronous GET request using the Fetch API. The response is processed in a sequence of then blocks, and errors are caught using the catch block. This style of handling asynchronous operations is known as Promises and is central to modern JavaScript development.
Error Handling With Promises
const errorPromise = new Promise((resolve, reject) => {
reject('Simulated error');
});
errorPromise.catch((error) => console.error('Error:', error));
new Promise((resolve, reject) => { reject('Simulated error'); }):
Output
- A new Promise is created with an executor function that immediately calls reject(‘Simulated error’). This means the promise is intentionally rejected with the error message ‘Simulated error’.
.catch((error) => console.error(‘Error:’, error))
- The catch method is used to handle errors in the Promise chain. It takes a callback function that will be executed when an error occurs in any preceding promise.
- In this case, the callback logs the error message to the console.
This example demonstrates how to handle errors in a Promise chain. If at any point in the chain a promise is rejected, the control jumps to the nearest catch block down the chain, allowing for centralized error handling.
It’s important to note that errors in Promises propagate down the chain until a catch block is encountered. If there’s no catch block in the chain, the error will result in an unhandled promise rejection. Proper error handling is crucial in asynchronous code to gracefully manage errors and prevent unhandled exceptions.
Examples of Using Promises in ES6 With Parallel Promises
Parallel Promises
const promise1 = Promise.resolve(1);
const promise2 = new Promise((resolve) => setTimeout(() => resolve(2), 1000));
Promise.all([promise1, promise2]).then((results) => console.log(results));
Output
Promise.resolve(1)
- Promise.resolve creates a resolved promise with the specified value. In this case, promise1 is a promise resolved with the value 1.
new Promise((resolve) => setTimeout(() => resolve(2), 1000))
- promise2 is a promise that resolves after a timeout of 1000 milliseconds (1 second). It’s resolved with the value 2.
Promise.all([promise1, promise2])
- The Promise.all method is used to wait for all promises in the given array to be resolved. It returns a new promise that is resolved with an array of the resolved values from each promise in the input array.
- In this case, it waits for both promise1 and promise2 to be resolved.
.then((results) => console.log(results))
- The then method is chained to the Promise.all call, and it takes a callback function that receives an array of the resolved values from all promises.
- In this example, when both promise1 and promise2 are resolved, the callback logs the array [1, 2] to the console.
This example demonstrates how Promise.all allows you to run multiple promises in parallel and wait for all of them to complete. It’s useful when you need to coordinate asynchronous operations and proceed when all promises have been fulfilled.
Examples of Using Promises in ES6 with AJAX
AJAX GET Request
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
Output
fetch(‘https://jsonplaceholder.typicode.com/posts/1’)
- The fetch function is used to make an HTTP GET request to the specified URL (https://jsonplaceholder.typicode.com/posts/1 in this case).
- The function returns a Promise that resolves to the Response object representing the response to the request.
.then(response => response.json())
- The first then method is used to handle the response from the server. It takes a callback function with the response object as its argument.
- response.json() is called to parse the response body as JSON, returning a Promise that resolves with the parsed JSON data.
.then(data => console.log(data))
- The second then method is used to handle the parsed JSON data. It takes a callback function that receives the parsed data as its argument.
- In this example, the callback logs the parsed data to the console.
.catch(error => console.error(‘Error:’, error))
- The catch method is used to handle errors that might occur during the fetch operation. If any error occurs at any point in the promise chain, it will be caught by this catch block.
- The callback function logs an error message to the console.
This code fetches data from the JSONPlaceholder API (a fake online REST API for testing and prototyping) using the Fetch API. The response is processed by parsing the JSON data and then logging it to the console. Error handling is also included to catch and log any errors that may occur during the fetch operation.
AJAX POST Request
const postData = { title: 'foo', body: 'bar', userId: 1 };
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(postData),
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
Output
const postData = { title: ‘foo’, body: ‘bar’, userId: 1 };
- postData is an object representing the data that will be sent in the POST request. It contains properties like title, body, and userId.
fetch(‘https://jsonplaceholder.typicode.com/posts’, { /* … */ })
- The fetch function is used to make an HTTP POST request to the specified URL (https://jsonplaceholder.typicode.com/posts). The second parameter is an options object that configures the request.
- The method is set to ‘POST’, indicating that it’s a POST request. The headers include information about the request, specifying that the content type is JSON. The body property contains the stringified JSON data.
.then(response => response.json())
- The first then method is used to handle the response from the server. It takes a callback function with the response object as its argument.
- response.json() is called to parse the response body as JSON, returning a Promise that resolves with the parsed JSON data.
.then(data => console.log(data))
- The second then method is used to handle the parsed JSON data. It takes a callback function that receives the parsed data as its argument.
- In this example, the callback logs the parsed data to the console.
.catch(error => console.error(‘Error:’, error))
- The catch method is used to handle errors that might occur during the fetch operation. If any error occurs at any point in the promise chain, it will be caught by this catch block.
- The callback function logs an error message to the console.
This code sends a POST request to the JSONPlaceholder API with the specified data (postData). The server responds, and the response is processed by parsing the JSON data and logging it to the console. Error handling is also included to catch and log any errors that may occur during the fetch operation.
Chaining AJAX Requests
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json())
.then(post => fetch(`https://jsonplaceholder.typicode.com/users/${post.userId}`))
.then(response => response.json())
.then(user => console.log(user))
.catch(error => console.error('Error:', error));
Output
Initial GET Request
- fetch(‘https://jsonplaceholder.typicode.com/posts/1’) initiates an HTTP GET request to retrieve information about a post with ID 1 from the JSONPlaceholder API.
- The response is processed using the first .then block.
.then(response => response.json())
- The first then block is used to handle the response from the initial GET request. It takes a callback function with the response object as its argument.
- response.json() is called to parse the response body as JSON, returning a Promise that resolves with the parsed JSON data (representing the post).
Subsequent GET Request
- The resolved post data is used in the next .then block, where a new GET request is made to retrieve information about the user associated with the post.
- fetch(https://jsonplaceholder.typicode.com/users/${post.userId}`)` initiates an HTTP GET request using the userId obtained from the previous response.
.then(response => response.json())
- The second then block handles the response from the subsequent GET request. It parses the response body as JSON, returning a Promise that resolves with the parsed JSON data (representing the user).
.then(user => console.log(user))
The third then block processes the user data obtained from the second AJAX request. It logs the user data to the console.
Error Handling
- The .catch block is included to handle any errors that may occur during the entire chain of promises. If an error occurs at any step, it will be caught and logged.
This code demonstrates chaining AJAX requests where the result of one request influences the URL of the subsequent request. It simulates retrieving information about a post, extracting the user ID from that post, and then fetching details about the user associated with that post. The final user data is then logged into the console.
Examples of Using Promises in ES6 With Timeout and Race Conditions
Timeout with Promises
const timeoutPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise resolved after 3 seconds');
}, 3000);
});
timeoutPromise.then((result) => console.log(result));
Output
new Promise((resolve, reject) => { /* … */ })
- A new Promise is created with an executor function. The executor function takes two parameters, resolve and reject. In this case, resolve is used to fulfill the promise.
setTimeout(() => resolve(‘Promise resolved after 3 seconds’), 3000);
- Within the executor function, a setTimeout is used to simulate an asynchronous operation. After 3 seconds (3000 milliseconds), the resolve function is called to fulfill the promise with the specified value (‘Promise resolved after 3 seconds’).
timeoutPromise.then((result) => console.log(result));
- The then method is used to handle the resolved value of the promise. It takes a callback function that will be executed when the promise is successfully resolved.
- In this case, the callback logs the resolved value (‘Promise resolved after 3 seconds’) to the console.
This example demonstrates how to create a Promise that includes a timeout. After a specified time, the Promise is resolved. This is useful in scenarios where you want to introduce a delay in your asynchronous code or perform an action after a certain period.
Promise Race
const promise1 = new Promise((resolve) => setTimeout(() => resolve('Promise 1'), 2000));
const promise2 = new Promise((resolve) => setTimeout(() => resolve('Promise 2'), 1000));
Promise.race([promise1, promise2]).then((result) => console.log(result));
Output
new Promise((resolve) => setTimeout(() => resolve(‘Promise 1’), 2000))
- promise1 is a Promise that resolves after a timeout of 2000 milliseconds (2 seconds). It is fulfilled with the value ‘Promise 1’.
new Promise((resolve) => setTimeout(() => resolve(‘Promise 2’), 1000))
- promise2 is another Promise that resolves after a timeout of 1000 milliseconds (1 second). It is fulfilled with the value ‘Promise 2’.
Promise.race([promise1, promise2])
- The Promise.race method is used to race multiple promises against each other. It takes an array of promises and returns a new promise.
- This new promise settles (resolves or rejects) as soon as the first promise in the array settles.
.then((result) => console.log(result))
- The then method is used to handle the result of the Promise.race. It takes a callback function that will be executed when the first promise in the array settles.
- In this example, when either promise1 or promise2 resolves first, the callback logs the result to the console.
Promise.race is useful when you have multiple asynchronous operations, and you want to react as soon as the first one is completed, regardless of whether it’s a success or failure. In this example, it logs the result of the first resolved promise to the console.
Further Reading
Building Dynamic Web Applications with the MERN Stack
Spring Framework Practice Problems and Their Solutions
From Google to the World: The Story of Go Programming Language
Why Go? Understanding the Advantages of this Emerging Language
Creating and Executing Simple Programs in Go
20+ Interview Questions on Go Programming Language