Skip to content

Promises

This lesson explains Promises in JavaScript with beginner-friendly examples, practical use cases, and clear best practices.

JavaScript Promises Overview

JavaScript Promises are objects that represent the eventual success or failure of an asynchronous operation. Promises make asynchronous JavaScript easier to write, read, and maintain compared to deeply nested callbacks.

Promises are commonly used for API calls, timers, file operations, database requests, lazy loading, background tasks, and modern asynchronous workflows. They work with then(), catch(), finally(), and are the foundation of async/await.

Promise Concept Description Common Usage
Pending Initial state before success or failure. Waiting for async result.
Fulfilled Operation completed successfully. Handle success data.
Rejected Operation failed with an error. Handle errors.
then() Runs when promise is fulfilled. Process successful result.
catch() Runs when promise is rejected. Error handling.
finally() Runs after success or failure. Cleanup and loading states.

JavaScript Promise Example

const getUser = new Promise(function(resolve, reject) {
  const success = true;

  if (success) {
    resolve("User loaded successfully");
  } else {
    reject("Failed to load user");
  }
});

getUser
  .then(function(result) {
    console.log(result);
  })
  .catch(function(error) {
    console.log(error);
  })
  .finally(function() {
    console.log("Promise completed");
  });

This example creates a promise and handles success using then(), failure using catch(), and cleanup using finally().

Top 10 JavaScript Promise Examples

The following examples show common Promise patterns used in API calls, async workflows, timers, error handling, parallel execution, and modern JavaScript applications.

# Example Syntax
1 Create Promise const p = new Promise(function(resolve) { resolve("Done"); });
2 Resolve Promise Promise.resolve("Success")
3 Reject Promise Promise.reject("Error")
4 Handle Success promise.then(function(result) { console.log(result); });
5 Handle Error promise.catch(function(error) { console.log(error); });
6 Finally Cleanup promise.finally(function() { console.log("Done"); });
7 Promise Chain promise.then(stepOne).then(stepTwo).catch(handleError);
8 Promise.all() Promise.all([getUsers(), getOrders()])
9 Promise.race() Promise.race([fastTask(), slowTask()])
10 Promise.allSettled() Promise.allSettled([getUsers(), getOrders()])

Best Practices

  • Use promises to avoid deeply nested callback code.
  • Always handle promise rejections using catch().
  • Use finally() for cleanup tasks such as hiding loaders.
  • Use Promise.all() for independent tasks that must all succeed.
  • Use Promise.allSettled() when you need results even if some tasks fail.
  • Use Promise.race() when the first settled result matters.
  • Use Promise.any() when the first successful result matters.
  • Prefer async/await for complex asynchronous workflows.

Common Mistakes

  • Forgetting to return a promise inside a then() chain.
  • Not handling rejected promises.
  • Using Promise.all() when partial failures should be allowed.
  • Creating unnecessary promises around already promise-based APIs.
  • Mixing callbacks and promises in confusing ways.
  • Assuming promises make slow operations faster by themselves.
  • Forgetting that promises are asynchronous even when already resolved.

Key Takeaways

  • A Promise represents a future success or failure value.
  • Promises have three states: pending, fulfilled, and rejected.
  • then() handles successful results.
  • catch() handles errors.
  • finally() runs cleanup logic after success or failure.
  • Promise methods such as all(), race(), any(), and allSettled() help manage multiple async tasks.
  • Promises are the foundation of async/await.

Pro Tip

Use Promise.all() when every task must succeed, and use Promise.allSettled() when you want to inspect all results even if some promises fail.