Skip to content
Latchkey

What Is a Promise? A Placeholder for a Future Value

A promise is an object that stands in for a value that is not ready yet, representing the eventual success or failure of an asynchronous operation.

A promise (called a future in some languages) is a handle to a result that will exist later. Instead of passing a callback to be invoked, an async function returns a promise immediately. You attach handlers for when it succeeds or fails, and the promise notifies them once the operation completes. Promises chain cleanly and underpin async/await.

The states of a promise

A promise is pending until the operation finishes, then either fulfilled with a value or rejected with an error. Once settled, its state never changes. Handlers attached with then and catch run when the promise settles, even if that already happened.

Why promises beat raw callbacks

  • They chain with then instead of nesting, flattening async flows.
  • Errors propagate down the chain to a single catch.
  • They compose: wait for all, or race several, with built-in helpers.
  • They are the foundation async/await is built on.

Promises and async/await

Async/await is sugar over promises. An async function returns a promise, and await pauses until a promise settles, then yields its value or throws its error. Understanding promises is understanding what async/await does underneath.

Common promise mistakes

Not returning a promise from a chain breaks ordering. Forgetting a catch leaves rejections unhandled. Creating a promise but never awaiting it means its work and errors are silently lost, a frequent source of subtle bugs.

A quick example

Calling fetch(url).then(res => res.json()).catch(err => report(err)) returns a promise, parses the response when it arrives, and routes any failure to a single error handler.

Promises in CI

Unhandled promise rejections and unawaited promises cause flaky, order-dependent test failures that come and go on loaded runners. Latchkey can auto-retry transient failures while you track down the unhandled rejection, so a single intermittent failure does not block your pipeline.

Key takeaways

  • A promise represents a future value that will either fulfill with a result or reject with an error.
  • Promises chain and compose, fixing the nesting and error handling of raw callbacks.
  • Async/await is built on promises; unhandled rejections cause flaky tests.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →