How to use Promise in TypeScript

How to use Promise in TypeScript

·

2 min read

Introduction

Asynchronous programming is an essential part of modern web development, as it allows us to perform tasks that may take time to complete, such as making API calls and reading from a database, without blocking the main thread.

Promises are a powerful feature that helps us to manage asynchronous operations more elegantly and concisely.

In this article, we will explore how to use promises in TypeScript to write efficient and robust asynchronous code.

What are promises?

A promise is an object that represents a value, that may not be available yet, but will be resolved at some point in the future. A promise provides a cleaner and more readable way to handle asynchronous operations compared to traditional callback-based approaches.

Syntex:

type ResolveType = (val: string) => void;
type RejectType = (err: string) => void;

let executor = (resolve : ResolveType, reject : RejectType) =>{
    // some Asynchronous operations...
    let isOperationSuccessful = true;
    if(isOperationSuccessful) resolve("Got data!");
    else reject("Something went wrong!");
}
let promiseObj = new Promise(executor);

promiseObj.then((val:string) =>{console.log(val) }); // Got data!
promiseObj.catch((err:string) =>{console.log(err) }); // Something went wrong!

In the above example, we can see that a promise object is created using a Promise constructor. The Promise constructor takes a callback function as an argument. This callback is called the executor function. The executor function takes two callback functions as arguments:

  • resolve: it is called when the asynchronous operation completes successfully.

  • reject: it is called when the asynchronous operation failed for some reason.

Both resolve and reject are function types and they take an argument and don't return anything.

Example:

Let's understand promises with one more example:

type ResolveType = (val: number[]) => void;
type RejectType = (val: Error) => void;

const executor = (resolve : ResolveType, reject: RejectType) => {
    setTimeout(() => {
      const apiData = [1,2,3];
      if (apiData) {
        resolve(apiData); // Resolve the promise with the fetched data
      } else {
        reject(new Error("Failed to fetch data")); // Reject the promise with an error if fetching fails
      }
    }, 2000)
}

function fetchData(): Promise<number[] | Error> {
  return new Promise( executor);
}

fetchData()
  .then((data) => {
    console.log("Fetched data:", data);
  })
  .catch((err) => {
    console.error("Failed to fetch data:", err);
  });

In the above example, the fetchData() function returns a promise that represents the result of a simulated asynchronous data fetching operation. The promise is resolved with the fetched data if it's successful or rejected with an error if it fails.

Then, We can use the .then() method to handle the resolved case, and the .catch() method to handle the rejected case.