-1

I'm experimenting with javascript function as object and async. Why Product2 below is never called ?

function Product(title) {
  this.title = title;
  this.getInfo = function() {
    return this.title;
  }
  return this;
}

async function Product2(title) {
  this.title = title;
  this.getInfo = function() {
    return this.title;
  }
  console.log(this.title)
  return this;
}

async function main() {
  console.log("start")


  var product = new Product("car");
  console.log(product.getInfo());

  var product2 = await new Product2("car 2");
  console.log(product2.getInfo());

  console.log("end")
}

main();
DBS
  • 9,110
  • 4
  • 35
  • 53
user310291
  • 36,946
  • 82
  • 271
  • 487
  • 1
    I don't think constructor functions can be async, or at least I don't get the purpose of them. See similar https://stackoverflow.com/questions/43431550/async-await-class-constructor – evolutionxbox May 20 '22 at 08:15
  • `new` doesn't make sense with an async function. Yet it is weird that it apparently just hangs. – VLAZ May 20 '22 at 08:17
  • 4
    @VLAZ firefox throws a "Product2 is not a constructor" error. – evolutionxbox May 20 '22 at 08:19
  • @evolutionxbox ok, that makes sense now. I just wasn't looking at the browser console, I copied the snippet and ran it. That error doesn't show up there. – VLAZ May 20 '22 at 08:20

3 Answers3

2

Not every function is a constructor. Some quotes from the ECMAScript specification clarify this:

Essential Internal Methods

A function object is an object that supports the [[Call]] internal method. A constructor is an object that supports the [[Construct]] internal method. [...] A function object is not necessarily a constructor and such non-constructor function objects do not have a [[Construct]] internal method.

Async functions are functions that are in the non-constructor category:

CreateDynamicFunction:

NOTE: Functions whose kind is async are not constructible and do not have a [[Construct]] internal method or a "prototype" property.

And:

AsyncFunction Instances:

AsyncFunction instances are not constructors and do not have a [[Construct]] internal method. AsyncFunction instances do not have a prototype property as they are not constructible.

Other examples of functions that cannot be constructors:

Function Instances - prototype:

Function objects created using Function.prototype.bind, or by evaluating a MethodDefinition (that is not a GeneratorMethod or AsyncGeneratorMethod) or an ArrowFunction do not have a "prototype" property.

Your example code actually runs into an exception because of the above reasons:

Uncaught (in promise) TypeError: Product2 is not a constructor

(for some reason this exception is not logged in the Stack Snippet, but a browser will show it in their console)

trincot
  • 317,000
  • 35
  • 244
  • 286
  • "*for some reason this exception is not logged in the Stack Snippet*" it's because it fails in a promise and the Stack Snippets don't show async failures. – VLAZ May 20 '22 at 09:56
  • Would be good if Stack Snippets were improved to output such uncaught exceptions. – trincot May 20 '22 at 09:58
  • Would be, I agree. IIRC, it's actually an open source project but I can't remember where to find it. It might accept pull requests. – VLAZ May 20 '22 at 10:01
1
async function Product2(title)

As this is async, There should be an uncaught TypeError when you are doing this:

var product2 = await new Product2("car 2");

cause Product2 is not a constructor anymore.

A function marked with async will return a promise.

A constructor on the other hand returns the object it is constructing. Thus we have a situation where you want to both return an object and a promise: an impossible situation.

Shuvo
  • 2,431
  • 1
  • 17
  • 9
-1

new Product2 will create an instance of an object of product2

You cannot use await and new keyword together.

  • "*new Product2 will create an instance of an object of product2*" no, it will not since you cannot call an async function with `new`. "*You cannot use await and new keyword together.*" this is also wrong. It *is* syntactically valid code. Whether it makes sense logically is a different matter, however, a function called with `new` *can* return a promise, thus `await new foo()` can be valid code: https://jsbin.com/yevuwerile/edit?js,console – VLAZ May 20 '22 at 08:25