Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ES6 - decide if object or promise

Is there a simple and elegant way to determinate if variable is promise or object in javascript (es6)?

I have a variable

let payment;

and at one time in app, it can be either promise or object with real values. I know I can test it it contains some properties like

if (payment.amount)

but this doesn't seems like an elegant solution to me, because properties (data structure) can change in time. Till now I was using

if (typeof payment === 'object')

but I've just figured out, that promises are basically also objects. So this condition is always true.

Is it possible to tell if it's a promise or object with real data?

like image 858
Patrik Šimunič Avatar asked Mar 26 '17 20:03

Patrik Šimunič


People also ask

How do you check an object is a Promise or not?

To check if a value is promise, check if the type of the value is an object and has a property named then of type function, e.g. typeof p === 'object' && typeof p. then === 'function' . If both conditions return true , the value is a promise.

Is Promise a function or object?

Essentially, a promise is a returned object to which you attach callbacks, instead of passing callbacks into a function.

How do you check if Promise is resolved or rejected?

The ES6 Promise constructor does not have a property that can tell you the state of the promise. You need to do something like this: import p from './promise. js' var isResolved = false; p.

When should we use Promise in JavaScript?

Promises are used to handle asynchronous operations in JavaScript. They are easy to manage when dealing with multiple asynchronous operations where callbacks can create callback hell leading to unmanageable code.


3 Answers

Don't try to find out. Just make it always a promise.

payment = Promise.resolve(payment);

Promise.resolve creates a new promise object. If the value passed is itself a promise, the is resolved or rejected when the original one is. If it is anything else, the new promise is resolved immediately with that value.

like image 125
lonesomeday Avatar answered Oct 03 '22 21:10

lonesomeday


As with all other native objects, you can use instanceof with the Promise constructor:

if (payment instanceof Promise)

However, if you don't know whether it's a native promise or from a custom library, you will usually want to detect a thenable by checking whether it has a .then method.

But you never really need to distinguish them (other than for debugging purposes). If there is a chance that something is a promise, you will always need to wait for, and construct a promise from it anyway. You don't need to do the distinction yourself, you can just use Promise.resolve to cast either promise, thenable or plain object to a promise of your favoured implementation - that's how Promise interoperability was designed in the first place, so it will absolutely work.

const promise = Promise.resolve(payment).then(value => {
    // value: always a plain value
}); // promise: always a promise
like image 44
Bergi Avatar answered Oct 03 '22 19:10

Bergi


Check if it has a property then that is a function:

if(payment != null && typeof payment.then === 'function')
  // is a promise
else
  // is not a promise

As far as I know, this is the only proper way to check if something is a promise (or a "promise-like" thenable), taking into account all different possible promise implementations.

like image 24
Frxstrem Avatar answered Oct 03 '22 19:10

Frxstrem