JavaScript Promises & Async/Await

Promises represent a value that may be available now, later, or never. Async/Await is modern syntax that makes working with promises easier.

1) Creating a Promise

A promise is created with new Promise() and either resolves or rejects.


const p = new Promise((resolve, reject) => {
  setTimeout(() => resolve('done'), 1000);
});

2) then / catch / finally

Handle resolved values with then, errors with catch, and cleanup with finally.


p
  .then(res => console.log(res))
  .catch(err => console.error(err))
  .finally(() => console.log('Always runs'));

3) Promise Chaining

Each then returns a new promise, allowing sequential async steps.


const chain = Promise.resolve(2);
chain
  .then(n => n * 2)
  .then(n => n + 1)
  .then(res => console.log(res)); // 5

4) Promise.all & Promise.race

Promise.all waits for all promises; Promise.race resolves/rejects with the first one.


const p1 = Promise.resolve('A');
const p2 = Promise.resolve('B');

Promise.all([p1, p2]).then(res => console.log(res));
Promise.race([p1, p2]).then(res => console.log(res));

5) Async / Await

Async functions return promises. await pauses until a promise resolves.


async function fetchData() {
  const res = await Promise.resolve('Data loaded');
  console.log(res);
}
fetchData();

6) Error Handling in Async Functions

Wrap await calls in try...catch for errors.


async function run() {
  try {
    const res = await Promise.reject('Oops!');
    console.log(res);
  } catch(e) {
    console.error(e);
  }
}
run();
Tip: Use async/await for readability, but remember it’s still promises under the hood. For parallel async tasks, use Promise.all.