DEV Community 👩‍💻👨‍💻

DEV Community 👩‍💻👨‍💻 is a community of 963,274 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in

Posted on • Updated on

Elegant way to check if a Promise is pending


There's no solid way to check if a Promise is pending or finished, at least not in Node.js, so I wrote this simple snippet back in few months ago while I was searching for a simple way. I couldn't' find anything with one line max that will check the state of a promise so I came up with this simple solution. I have posted this solution on StackOverflow too. It's nothing special just an elegant & hacky way but works flawlessly on every Node.js version from 8~14. It's not stable though and the rational solution here should be a native method inside V8's core to check if a promise is pending or not.

The trick

If we take the whole object of a promise and inspect it using the inspect method from the native libraries of Node.js, we will get either 'Promise { <pending> }' while pending or 'Promise { undefined }' when finished.
Now if we check the string for the word pending we could define the state and check if a promise is pending or not using the following one line: util.inspect(myPromise).includes("pending").

Here's an example to get you started:

const util = require("util")

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));

(async ()=>{
  let letmesleep = sleep(13000)
Enter fullscreen mode Exit fullscreen mode


Enter fullscreen mode Exit fullscreen mode


If you liked this article please follow me on Twitter :)

Top comments (7)

somedood profile image
Basti Ortiz • Edited on

I mean this is cool and all, but I'm not really sure when one would ever want to know when a promise is "pending".

It's a fun experiment for the sake of learning, but usually, one would be better off just waiting until the Promise#then handler is fired.

However, if it is indeed "necessary" to do so (though I highly doubt that there is no better approach), you can use the Promise#then handler to achieve it more "elegantly" and concisely without the use of Node's meta tools.

let isPending = true;
  .then(() => { isPending = false; });
Enter fullscreen mode Exit fullscreen mode
devcrafter91 profile image
Drakos Author • Edited on

If you're dealing with a scenario where you have a lot of promises and you wanted to just check the state for reporting or something, you must then define a bunch of variables for every promise which is ugly imho.

callmelann profile image

Checkout something like this, yeah, everything is just the Promise#then.

I never thought to check the "pending" even in a complex scenario. It is not something I wanted to grab and go, I'll come back later. Maybe you need it if you deal with coroutine or infinite loop but JS don't need that and I never done that on function generator too since there are always a way:

Since we can keep promise instance around, we can always append more or chain Promise#then to structure the flow we want.

somedood profile image
Basti Ortiz • Edited on

In that case, assuming a Node environment as in your example in the article, wouldn't it be better (and more readable) to implement an event emitter instead?

It seems to me that promises may be the wrong abstraction for the job.

jakobrosenberg profile image
Jakob Rosenberg

Promise.all is great if you're working with a static array, but what if your array is dynamic? Promises added between the wait and the resolve will then be ignored.

To solve that you could do something like

 * @param {Promise<any>[]} promises
const dynamicPromiseAll = async (promises) => {
  const result = await Promise.all(promises);
  const hasPending = => util.inspect(promise).includes("pending")).filter(Boolean).length;
  return hasPending ? dynamicPromiseAll(promises) : result;
Enter fullscreen mode Exit fullscreen mode
samwisela profile image

Just wanted to thank you.

This is all I needed.

Why? I am doing an animation in VR and the Avatar triggers the animation AND I do not want it retriggered until it ends. Like an elevator ride that I do not want interrupted. This worked great! If you're ever in ASVR (AltSpaceVR) come and check out what I'm talking about. Like, a Hot Air Balloon Rise...

callmelann profile image

I'm not sure if I understand correctly, but maybe you not using Promise in a way you imagine the outcome.

If you chain the promises (to put observe it in the middle of the chain) the original consumer of the final promise in the chain doesn't affected as long as you pass the resolve value around.

If you append more .then() to the original promise, you can get notified and the consumer of the promise unaffected.

It doesn't affect the performance or lag unless you add sync I/O, it is just code structure. I believe there will be an extra tiny processing of inspect above then using plain Promise#then

Visualizing Promises and Async/Await 🤯

async await

☝️ Check out this all-time classic DEV post