Codectionary / Developer documentation / JavaScript

Promises

A Promise represents a value that may not be available yet - the eventual result of an asynchronous operation. It exists in one of three states: pending, fulfilled, or rejected. then() handles a successful result, catch() handles an error, and finally() runs regardless of outcome. Promises are the foundation that async/await is built on top of.

Syntax

new Promise((resolve, reject) => { })
promise.then(onSuccess).catch(onError)

Examples

Creating and Using a Promise

Wrapping an asynchronous operation in a Promise.

function fetchUserData(userId) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (userId > 0) {
        resolve({ id: userId, name: "Alice" });
      } else {
        reject(new Error("Invalid user ID"));
      }
    }, 1000);
  });
}

fetchUserData(1)
  .then(user => console.log(user))
  .catch(error => console.log(error.message));

Chaining Promises

Each then() returns a new promise, allowing sequential operations.

fetch("/api/user/1")
  .then(response => response.json())
  .then(user => {
    console.log("User:", user.name);
    return fetch(`/api/posts/${user.id}`);
  })
  .then(response => response.json())
  .then(posts => console.log("Posts:", posts))
  .catch(error => console.log("Something failed:", error.message))
  .finally(() => console.log("Request cycle complete"));

Best practices

  • Always add a .catch() to handle rejected promises - an unhandled rejection can silently fail or crash depending on the environment
  • Return a value or another promise from inside .then() when chaining, so the next .then() receives the right data
  • Prefer async/await over long .then() chains in most cases - it reads more like familiar synchronous code
  • Use .finally() for cleanup logic (hiding a spinner, closing a connection) that should run whether the promise succeeds or fails

At a glance

Purpose
Application logic and interaction
File extension
.js ยท .mjs
Runs in
Browsers and JavaScript runtimes
Usually used with
HTML, CSS and Web APIs

Specifications & further reading

Related JavaScript documentation

Async/Await
Async/await is modern JavaScript syntax for handling asynchronous operations, making asynchronous code look and behave like synchronous code. The async keyword marks a function as asynchronous, and await pauses execution until a Promise resolves. This approach makes asynchronous code more readable and easier to understand than traditional Promise chains or callbacks.
Promise.all(), allSettled(), race(), any()
These static methods handle multiple promises at once. Promise.all() waits for every promise to resolve, but rejects immediately if any one fails. allSettled() waits for all to finish regardless of outcome, giving you both successes and failures. race() resolves or rejects as soon as the first promise settles. any() resolves as soon as the first one succeeds, ignoring rejections unless all fail.
Fetch API
The Fetch API provides a modern, promise-based way to make HTTP requests, replacing the older XMLHttpRequest. fetch() returns a promise that resolves to a Response object once headers are received - note that a Response is only considered "ok" if the status is 2xx, so checking response.ok is essential, since fetch() does not reject on HTTP error statuses.
Web Workers
Web Workers run JavaScript on a separate background thread, away from the main UI thread, so expensive computations do not freeze the page. Communication between the main script and a worker happens through message passing with postMessage() and the onmessage event handler, rather than shared memory - workers cannot directly access the DOM.