How to Determine a JavaScript Promise’s Status

By  on  

Promises have changed the landscape of JavaScript. Many old APIs have been reincarnated to use Promises (XHR to fetch, Battery API), while new APIs trend toward Promises. Developers can use async/await to handle promises, or then/catch/finally with callbacks, but what Promises don't tell you is their status. Wouldn't it be great if the Promise.prototype provided developers a status property to know whether a promise is rejected, resolved, or just done?

My research led me to this gist which I found quite clever. I took some time to modify a bit of code and add comments. The following solution provides helper methods for determining a Promise's status:

// Uses setTimeout with Promise to create an arbitrary delay time
// In these examples, a 0 millisecond delay is 
// an instantly resolving promise that we can jude status against
async function delay(milliseconds = 0, returnValue) {
  return new Promise(done => setTimeout((() => done(returnValue)), milliseconds));
}

// Promise.race in all of these functions uses delay of 0 to
// instantly resolve.  If the promise is resolved or rejected,
// returning that value will beat the setTimeout in the race

async function isResolved(promise) {
  return await Promise.race([delay(0, false), promise.then(() => true, () => false)]);
}

async function isRejected(promise) {
  return await Promise.race([delay(0, false), promise.then(() => false, () => true)]);
}

async function isFinished(promise) {
  return await Promise.race([delay(0, false), promise.then(() => true, () => true)]);
}

A few examples of usage:

// Testing isResolved
await isResolved(new Promise(resolve => resolve())); // true
await isResolved(new Promise((_, reject) => reject()));  // false

// Testing isRejected
await isRejected(new Promise((_, reject) => reject())); // true

// We done yet?
await isFinished(new Promise(resolve => resolve())); // true
await isFinished(new Promise((_, reject) => reject()));  // true

Developers can always add another await or then to a Promise to execute something but it is interesting to figure out the status of a given Promise. Is there an easier way to know a Promise's status? Let me know!

Recent Features

  • By
    Welcome to My New Office

    My first professional web development was at a small print shop where I sat in a windowless cubical all day. I suffered that boxed in environment for almost five years before I was able to find a remote job where I worked from home. The first...

  • By
    9 Mind-Blowing Canvas Demos

    The <canvas> element has been a revelation for the visual experts among our ranks.  Canvas provides the means for incredible and efficient animations with the added bonus of no Flash; these developers can flash their awesome JavaScript skills instead.  Here are nine unbelievable canvas demos that...

Incredible Demos

  • By
    Digg-Style Dynamic Share Widget Using the Dojo Toolkit

    I've always seen Digg as a very progressive website. Digg uses experimental, ajaxified methods for comments and mission-critical functions. One nice touch Digg has added to their website is their hover share widget. Here's how to implement that functionality on your site...

  • By
    Fullscreen API

    As we move toward more true web applications, our JavaScript APIs are doing their best to keep up.  One very simple but useful new JavaScript API is the Fullscreen API.  The Fullscreen API provides a programmatic way to request fullscreen display from the user, and exit...

Discussion

  1. Gordon
    function state(promise: Promise) {
        let state = "pending";
        promise.then(() => state = "fulfilled", () => state = "rejected");
        return () => state;
    }
    
    const p = Promise.resolve(42);
    const s = state(p);
    console.log(s());   //  pending
    setTimeout(() => {
        console.log(s());  //  fulfilled
    }, 0);
    

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!