Nov 8, 2016Last modified April 27, 2025

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 -

  1. pending - initial state
  2. fulfilled - action completed successfully
  3. 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 = [
        // 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();

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 -

// 1. Create a new XMLHttpRequest object
const xhr = new XMLHttpRequest();

// 2. Configure the request (HTTP method, URL, async flag)
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true);

// 3. Define what happens when the request completes
xhr.onload = function() {
  if (xhr.status >= 200 && xhr.status < 300) {
    // Success! Parse the JSON response
    const data = JSON.parse(xhr.responseText);
    console.log('Success:', data);
  } else {
    // Request finished but failed (e.g., 404)
    console.error('Error:', xhr.statusText);
  }
};

// 4. Handle network errors
xhr.onerror = function() {
  console.error('Network request failed');
};

// 5. Send the request
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; // Re-throw to let caller handle it
  }
}

// Usage
fetchUserData(1)
  .then(user => console.log('User fetched:', user))
  .catch(err => console.error('Error in caller:', err));