FSM Full Stack Masterclass
Platform under construction
JavaScript course badge

Async JavaScript

Advanced

Promises

A Promise represents work that will either fulfill with a value or reject with a reason.

loadData()
  .then(data => render(data))
  .catch(error => showError(error));

Async JavaScript

Promises model future success or failure.

A promise starts pending. It later becomes fulfilled or rejected. Once settled, it stays settled.

then handles fulfillment. catch handles rejection. finally runs after either outcome.

Promise chains return new promises, which lets you transform values step by step.

pending

Initial state before the result is known.

fulfilled

The operation completed successfully.

rejected

The operation failed.

settled

Either fulfilled or rejected.

Examples

Async code should show state, handle failure and avoid stale results.

Return transformed promises

function loadTitle() {
  return fetchData()
    .then(data => data.title);
}

Forgetting to return inside a chain

function loadTitle() {
  fetchData().then(data => data.title);
}

// The function returns undefined.

Code patterns

Reusable examples for quick reference.

These examples are the async patterns you will reuse: timers, promises, composition, await, fetch and cancellation.

Then chain

Transform a fulfilled value.

getNumber()
  .then(value => value * 2)
  .then(result => console.log(result));

Catch errors

Handle rejected promises.

loadData().catch(error => {
  console.error(error.message);
});

Finally cleanup

Runs after success or failure.

loadData().finally(() => {
  button.disabled = false;
});

Create promise

Wrap async completion carefully.

const delay = ms => new Promise(resolve => {
  setTimeout(resolve, ms);
});

Rules that matter

Make time visible in your code.

Async JavaScript is easier when every operation has clear pending, success, failure and cancellation behavior.

Return promises from functions

Callers need to wait or catch.

Catch rejection paths

Unhandled rejections are bugs.

Use finally for cleanup

Loading state should clear after either outcome.

Avoid nesting then chains

Return from then instead of nesting deeper.

Do not wrap promises unnecessarily

Many APIs already return promises.

Know settled state

A promise does not change again after fulfillment or rejection.

Production thinking

Reliable async code is what makes modern interfaces feel fast instead of fragile.

Why does this matter?

Promises are the foundation of modern async JavaScript, including fetch and async/await.

Accessibility

Promise-based UI should expose loading and error messages in readable text.

Production note

Production promise chains need consistent catch handling and cleanup.

SEO note

Promise failures during rendering can leave pages incomplete if not handled.

Live code lab

Change the HTML, CSS or JavaScript and run the result.

The preview runs inside an isolated iframe. The JavaScript is placed inside the HTML editor for now, so every example stays together and remains easy to understand.

Mini assignment

Try this now.

  • Make the promise reject.
  • Add finally and log cleanup.
  • Return a transformed value from then.

Practice assignment

Do this before moving to the next topic.

  1. Create one promise-returning function.
  2. Handle fulfillment with then.
  3. Handle rejection with catch.

Try it yourself

Resolve or reject a promise

Live preview

Self-check

Before you continue, prove that you understand Promises.

Advanced

If you can explain when the code runs, how it fails and what happens if it becomes irrelevant, you understand the async model.

  1. Can you explain pending?
  2. Can you explain fulfilled?
  3. Can you explain rejected?
  4. Can you explain then chains?
  5. Can you explain why returning promises matters?

Senior audit upgrade

Extra production context for Promises.

Promise model

A promise is a value representing future completion: pending, fulfilled or rejected.

start async work
  -> pending promise
  -> fulfilled value OR rejected reason
  -> then/catch/finally path