Promise.prototype.then()

then(onFulfilled)
Returns: Promise · Added in ves6 · Updated March 15, 2026 · Async APIs
promise async es6 javascript

The then() method attaches callback functions for the fulfillment and rejection cases of a Promise. It returns a new Promise, enabling method chaining for asynchronous operations.

Syntax

promise.then(onFulfilled)
promise.then(onFulfilled, onRejected)

Parameters

ParameterTypeDefaultDescription
onFulfilledfunctionundefinedCalled if the Promise is fulfilled. Receives the fulfillment value as an argument.
onRejectedfunctionundefinedCalled if the Promise is rejected. Receives the rejection reason (error) as an argument.

Return Value

A new Promise that:

  • Resolves with the return value of onFulfilled if called
  • Resolves with the original value if onFulfilled is not a function
  • Rejects with the error thrown by onRejected if it throws
  • Rejects with the original rejection reason if onRejected is not a function

Examples

Basic Usage

const promise = Promise.resolve(42);

promise.then(value => {
  console.log(value); // 42
  return value * 2;
}).then(double => {
  console.log(double); // 84
});

Chaining Multiple Promises

fetch("/api/user")
  .then(response => response.json()) // Returns a Promise
  .then(user => {
    console.log("User:", user.name);
    return fetch(`/api/posts/${user.id}`);
  })
  .then(response => response.json())
  .then(posts => {
    console.log("Posts:", posts.length);
  })
  .catch(error => {
    console.error("Request failed:", error);
  });

Handling Errors

fetchData()
  .then(data => processData(data))
  .then(result => console.log("Success:", result))
  .catch(error => {
    console.error("Failed:", error.message);
  });

Using Both Callbacks

const promise = Promise.reject(new Error("Initial error"));

promise.then(
  value => console.log("Fulfilled:", value),
  error => {
    console.log("Caught:", error.message); // "Caught: Initial error"
    return "Recovered value";
  }
).then(value => {
  console.log(value); // "Recovered value"
});

Returning Values vs. Promises

// Returning a non-Promise value
Promise.resolve(1)
  .then(x => x + 1) // 2
  .then(x => x * 2)  // 4
  .then(console.log);

// Returning a Promise (automatically chained)
Promise.resolve(1)
  .then(x => Promise.resolve(x + 1)) // Resolves to 2
  .then(x => Promise.resolve(x * 2))  // Resolves to 4
  .then(console.log);

Sequential Async Operations

async function loadFullStory(chapterId) {
  const chapter = await fetch(`/api/chapters/${chapterId}`)
    .then(r => r.json());
  
  const author = await fetch(`/api/authors/${chapter.authorId}`)
    .then(r => r.json());
  
  const reviews = await fetch(`/api/reviews?book=${chapter.bookId}`)
    .then(r => r.json());
  
  return { chapter, author, reviews };
}

Common Mistakes

Forgetting to Return

// WRONG: Missing return statement
fetch("/api/user")
  .then(response => response.json())
  .then(user => {
    console.log(user.name); // Works
  })
  .then(() => {
    console.log("User processed"); // user is undefined here!
  });

// CORRECT: Return the chain
fetch("/api/user")
  .then(response => response.json())
  .then(user => {
    console.log(user.name);
    return user;
  })
  .then(user => {
    console.log("User processed:", user.name);
  });

Not Handling Rejections

// WARNING: Unhandled rejection
fetch("/api/missing")
  .then(response => response.json());

// FIX: Always handle rejections
fetch("/api/missing")
  .then(response => response.json())
  .catch(error => {
    console.error("Request failed:", error.message);
  });

See Also