Promises, fetch and async/await in javascript
You can think of a promise in a javascript as a token that represents the eventual completion of some action.
Its like a CD receipt that you get when you put your money in a CD in bank. The receipt garuntees that youa are going to get a certain amount of money after a certain period of time.
A promise has three states -
- pending - initial state
- fulfilled - action completed successfully
- rejected - action failed
Here's how a promise is executed by JS engine and browser -
Promise Sytanx
// defining a promise
const myPromise = new Promise((resolve, reject)=>{
// do some action
if(success)
resolve(data);
else
reject(error);
});
// consuming a promise
myPromise
.then( data => { console.log(data) })
.catch( error => { console.log(error) })
// defining a promise
const myPromise = new Promise((resolve, reject)=>{
// do some action
if(success)
resolve(data);
else
reject(error);
});
// consuming a promise
myPromise
.then( data => { console.log(data) })
.catch( error => { console.log(error) })
Here's a simple example of a promise that resolves after a delay of 2 seconds.
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
wait(3000).then(()=> console.log('Hello! (after 3 seconds)'));
Promise.all
Promise.all() takes an array of Promises and returns a single Promise that:
- Resolves when all input Promises resolve (results are in an array, in order).
- Rejects immediately if any input Promise rejects.
async function tryPromiseAll(){
const apiPromises = [
// 1. Random User API - Get user data
fetch('https://api.thecatapi.com/v1/images/0XYvRd7oD'),
// 2. JSONPlaceholder API - Get a post
fetch('https://jsonplaceholder.typicode.com/posts/1'),
// 3. Open Weather Map API - Intention
fetch('https://api.openweathermap.org/data/2.5/weather?q=London&appid=invalid_key')
];
try{
const results = await Promise.all(apiPromises);
console.log(results);
}
catch(error){
const results = await Promise.allSettled(apiPromises);
results.forEach((result, index) => {
if(result.status === 'fulfilled'){
console.log(result.value.apiName + " succeeded with data - " + result.value.data);
}
});
}
}
tryPromiseAll();
async function tryPromiseAll(){
const apiPromises = [
// 1. Random User API - Get user data
fetch('https://api.thecatapi.com/v1/images/0XYvRd7oD'),
// 2. JSONPlaceholder API - Get a post
fetch('https://jsonplaceholder.typicode.com/posts/1'),
// 3. Open Weather Map API - Intention
fetch('https://api.openweathermap.org/data/2.5/weather?q=London&appid=invalid_key')
];
try{
const results = await Promise.all(apiPromises);
console.log(results);
}
catch(error){
const results = await Promise.allSettled(apiPromises);
results.forEach((result, index) => {
if(result.status === 'fulfilled'){
console.log(result.value.apiName + " succeeded with data - " + result.value.data);
}
});
}
}
tryPromiseAll();
async function tryPromiseAll(){
const apiPromises = [
fetch('https://api.thecatapi.com/v1/images/0XYvRd7oD'),
fetch('https://jsonplaceholder.typicode.com/posts/1'),
fetch('https://api.openweathermap.org/data/2.5/weather?q=London&appid=invalid_key')
];
try{
const results = await Promise.all(apiPromises);
console.log(results);
}
catch(error){
const results = await Promise.allSettled(apiPromises);
results.forEach((result, index) => {
if(result.status === 'fulfilled'){
console.log(result.value.apiName + " succeeded with data - " + result.value.data);
}
});
}
}
tryPromiseAll();
Fetch API
Fetch is a modern JavaScript API for making HTTP requests. It provides a more powerful and flexible way to fetch data from a server compared to the traditional XMLHttpRequest.
Here's how you would make a request with old XMLHttpRequest -
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true);
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
const data = JSON.parse(xhr.responseText);
console.log('Success:', data);
} else {
console.error('Error:', xhr.statusText);
}
};
xhr.onerror = function() {
console.error('Network request failed');
};
xhr.send();
Here's a basic example of how to use the Fetch API to fetch data from an API.
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) throw new Error('Network error');
return response.json(); // Parses JSON body (also a Promise)
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) throw new Error('Network error');
return response.json(); // Parses JSON body (also a Promise)
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
fetch() only rejects on network failures, not HTTP errors (e.g., 404). You should check response.ok to handle HTTP errors. Use .json(), .text(), or .blob() to parse the response body.
Here's how fetch works under the hood:
Async/Await
Async/await is a modern JavaScript feature that simplifies asynchronous code by allowing you to write asynchronous code in a synchronous style. It's built on top of Promises and provides a more readable and concise way to work with asynchronous operations.
Its a syntax sugar for promises.
Here's a basic syntax of how to use async/await to fetch data from an API.
async function myFunction() {
try {
const result = await someAsyncOperation();
console.log(result);
} catch (error) {
console.error(error);
}
}
async function myFunction() {
try {
const result = await someAsyncOperation();
console.log(result);
} catch (error) {
console.error(error);
}
}
- async: Marks a function as asynchronous (always returns a promise)
- await: Pauses execution until the promise settles (only works inside async functions)
Simple Example
async function fetchUserData(userId) {
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts/"+userId);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const userData = await response.json();
console.log(userData);
return userData;
} catch (error) {
console.error('Failed to fetch user:', error);
throw error;
}
}
fetchUserData(1)
.then(user => console.log('User fetched:', user))
.catch(err => console.error('Error in caller:', err));