jsguides

Promise.resolve()

The Promise.resolve() static method returns a Promise object that is resolved with a given value. It provides a way to wrap synchronous values into promises.

Syntax

Promise.resolve(value)

Parameters

ParameterTypeDescription
valueanyThe value to resolve with. Can be a plain value, a thenable, or an existing Promise

Return Value

  • If the value is a Promise, returns that Promise
  • If the value is a thenable (object with a then method), returns a Promise that follows that thenable
  • Otherwise, returns a new Promise resolved with the value

Examples

Basic Usage

// Resolve with a plain value
const promise = Promise.resolve(42);
promise.then(result => console.log(result)); // 42

// Shortcut for new Promise(resolve => resolve(value))
const data = Promise.resolve({ id: 1, name: "Alice" });

A thenable is any object that exposes a .then() method — it doesn’t have to be a native Promise. When you pass a thenable to Promise.resolve(), the returned promise adopts the thenable’s eventual state. This lets you work with promise-like objects from third-party libraries without worrying about whether they are real Promises.

Using with Thenables

// A thenable is any object with a .then() method
const thenable = {
  then(resolve, reject) {
    resolve(42);
  }
};

Promise.resolve(thenable).then(result => {
  console.log(result); // 42
});

When a function mixes synchronous and asynchronous code paths, the return type becomes unpredictable — sometimes a value, sometimes a Promise. Wrapping the result with Promise.resolve() normalises the interface so callers can always chain .then() or use await without checking what they received.

Ensuring a function always returns a Promise

function getData(id) {
  // If data is already available, wrap it
  // If it's a promise, return it as-is
  return Promise.resolve(cache[id] || fetchFromNetwork(id));
}

// This works whether the source is sync or async
const result1 = getData("cached-item");
const result2 = getData("remote-item");

Not every function that follows a callback pattern actually requires one. Synchronous functions like fs.readFileSync return values directly, and wrapping them with Promise.resolve() is all that’s needed to give them a promise-shaped return type. For async callbacks, use util.promisify or the Promise constructor instead.

Converting callback APIs

function readFilePromise(path) {
  return Promise.resolve(fs.readFileSync(path));
}

Key Behaviors

  • Identity function for promises: If passed a Promise, it returns that exact Promise (not a wrapper)
  • Thenables: Automatically adopts the state of thenables, waiting for their resolution
  • Undefined: Promise.resolve() returns a resolved Promise with undefined

Keep these behaviours in mind — they determine whether Promise.resolve() adds unnecessary wrapping or passes through efficiently.

Common Pitfalls

// AVOID: Unnecessary wrapping
const p = Promise.resolve(Promise.resolve(42));
// The inner Promise.resolve is redundant

// CORRECT: Direct pass-through
const p = Promise.resolve(existingPromise);

Microtask scheduling

Even when passing a plain (non-Promise) value to Promise.resolve(), the then callbacks are always invoked asynchronously — they are scheduled as microtasks, not executed immediately. This means code after Promise.resolve(value).then(fn) runs before fn does, even though the promise is already resolved.

Promise.resolve(42).then(v => console.log('async:', v));
console.log('sync');
// Output:
// sync
// async: 42

This is important to remember when reasoning about the order of operations in mixed synchronous/asynchronous code.

Promise.resolve() with a Promise argument

If you pass an existing Promise to Promise.resolve(), it returns that exact promise — not a new wrapper. Promise.resolve(p) === p is true when p is a native Promise. This makes Promise.resolve() a safe way to ensure you always have a Promise without creating redundant wrappers.

Normalizing mixed sync/async APIs

A common use of Promise.resolve() is in functions that may return either a plain value from a cache or a promise from a network call. Wrapping the return with Promise.resolve(value) ensures callers always get a promise regardless of which code path ran. This makes the function’s interface predictable: callers can always chain .then() or use await without checking whether the result is already a value.

When Promise.resolve() is the right tool

Promise.resolve() is the simplest way to turn an immediate value into a promise-shaped result. That is useful when a function may return either a raw value or a promise, and the caller wants to handle both with the same chain.

It is also handy when you want to start a promise chain from a known value without introducing extra branching. Because the returned promise is already fulfilled, it fits naturally into then() flows and async helper functions.

See Also