For AI agents: the complete documentation index is available at /tc39-atlas/en/llms.txt, the full documentation bundle is available at /tc39-atlas/en/llms-full.txt, and this page is available as Markdown at /tc39-atlas/en/proposals/year/2025/proposal-promise-try.md.
  • English
  • Promise.try S4

    Proposal details
    Proposal overview

    The proposal introduces Promise.try, a method to invoke a function and return a promise, handling both synchronous return values and thrown exceptions via promise semantics. It avoids the extra microtask delay of Promise.resolve().then(f), mirroring async function execution up to the first await.

    Note

    The README below comes from the upstream repository and may contain outdated stage or status metadata. Use the proposal details above as the current source of truth.

    Promise.try

    ECMAScript Proposal, specs, and reference implementation for Promise.try

    Spec drafted by @ljharb.

    This proposal is currently stage 4 of the process.

    Rationale

    A common use case that I, and many others, have, is that I have a function, f. This function may be async, and return a Promise, or it may not - I don’t wish to have to know. However, I'd like to wrap it in a Promise so that if it is async, or if it throws, I can lean on Promise semantics and .catch to handle it.

    The typical “easy to remember” way this is achieved in JS Promises is with Promise.resolve().then(f). This works great! It catches any exceptions thrown, and it Promise-wraps any thenable or value returned from the function. However, f is needlessly run asynchronously, on a future tick.

    If I want f to be run on the same tick - since, after all, it might be synchronously returning a value - or if I want parallel semantics with an async function up to the first await - then I need to use new Promise(resolve => resolve(f())). This achieves my goal, but is not ergonomic to write nor easy to remember.

    Using Promise.try(f), I can get the same semantics as the new Promise mess above, nicely mirroring async function, and allowing optimistically synchronous, but safe, execution of a function, and being able to work with a Promise afterwards. Yay!

    Userland implementations

    Further reading

    Naming

    The most common name is try, which has a clean parallel with a syntactic try block. A common alternative name is attempt, but this has been primarily for ES3 compatibility, and is not necessary here.

    Spec

    You can view the spec rendered as HTML.

    Polyfills