await with overloaded methods

Viewed 393

I have an ES6 class hierarchy. All of the classes in the hierarchy implement a draw() method. Some implement it synchronously but some need this method to be async.
How can I call draw() correctly in this sort of setup?
Is it possible to find if the method being called is async and only then call await on it's result?

3 Answers

You could check if the draw() has a .then function since all promises will have to implement that. If it does, use async, else execute directly

Check this answer on how to determine a promise How do I tell if an object is a Promise?

  if(draw.then) {  // all async await functions wrap the return into promises. So, this should 
    const resolvedData = await draw(); // store the data if you need to get the value
  else
    draw()

I wanted to avoid having to decla(r)e 100 methods as async for the sake of just the two that actually need it.

A function doesn't have to be async (ie: return a promise) to be awaited. A synchronous function can be awaited too. This means that if a promise is not returned by draw() (ie: your draw() method is synchronous), then the await will convert the returned value of draw() to a resolved promise which it then waits for and retrieves its value.

So, something like the following is possible:

function foo() { // returns a string
  return "foo";
}

async function bar() { // implicitly returns a promise
  return "bar"; 
}

(async function() {
  const fooStr = await foo(); // foo() is synchronous, but can be `await`ed still
  const barStr = await bar(); // bar() is asynchronous, and can be `await`ed
  console.log(fooStr, barStr);
})();

With this in mind, you don't need to know if draw() is synchronous or not, instead, you can always await the draw() method, regardless of its return type.

You can check your function if it is async function by using Object.prototype.constructor.name.

var object = {
  draw: async function() {}
}
var object1 = {
  draw: function() {}
}

console.log(object.draw.constructor.name);
console.log(object1.draw.constructor.name);

Related