Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async constructors? (new Foo() returning Promise<Foo>) #563

Closed
tabatkins opened this issue May 31, 2018 · 6 comments
Closed

Async constructors? (new Foo() returning Promise<Foo>) #563

tabatkins opened this issue May 31, 2018 · 6 comments

Comments

@tabatkins
Copy link
Contributor

Per the current spec:

The prose definition of a constructor must either return an IDL value of a type corresponding to the interface the [Constructor] extended attribute appears on, or throw an exception.

This means that if you want to only provide an async way to obtain an object, you can't use a constructor - you have to omit the constructor (so it default-throws), and then use a factory function that actually constructs the object.

Is there any appetite for being able to mark a constructor as async in some way, such that it can return a Promise for the instance?

@inexorabletash
Copy link
Member

inexorabletash commented May 31, 2018

So to be clear, the usage would be something like this?

const sheet = await new StyleSheet(text);

The syntax is nice and clean in isolation. Questions that occur to me:

  • Are all constructors of an interface required to be async if any are? If not, is that confusingly inconsistent for developers or problematic for implementers? If so, does that have any weird consequences? (like allowing future polyfills/helpers to synchronously construct an empty instance, then populate it asynchronously)
  • This is possible today in non-IDL JS... are there examples of libraries that do this? If so, what has developer feedback been? If not, how brave do we feel about baking a (yet another...) potentially non-idiomatic pattern into the platform?
  • Any non-JS language examples out there?

@annevk
Copy link
Member

annevk commented Jun 1, 2018

See also w3ctag/design-principles#44.

@tabatkins
Copy link
Contributor Author

So to be clear, the usage would be something like this?

Yes, exactly. (Or munging several into a Promise.all(), etc.)

Are all constructors of an interface required to be async if any are?

I suspect we'd want to make that restriction, yes. "Multiple" constructors are just a syntax nicety for doing type-checking over complicated argument lists; they're all implemented as a single JS function. If we pretend that this function is designated async in JS syntax, then there's no way to return a non-Promise.

This is possible today in non-IDL JS... are there examples of libraries that do this?

Dunno! This should be investigated.

@TimothyGu
Copy link
Member

While await new does look pretty clean if nonidiomatic, using .then and .catch looks a bit odd:

return new StyleSheet(text).then(actualSheet => actualSheet.doSomethingElse());

In general I would prefer preserving the new keyword to what's already there rather than introducing something new into the platform. I would not be surprised at all to find style guides out there that expressly prohibit returning from a constructor – and in fact I would suggest the same to most JavaScript programmers.

@justinfagnani
Copy link

I don't think this is a good idea. Even though JavaScript is flexible enough to do otherwise, a constructor should return an instance of the class being constructed. ie, new Foo() instanceof Foo should always be true. Static factory methods are a fine way to asynchronously create instances.

@domenic
Copy link
Member

domenic commented Sep 13, 2018

Sounds like we have a rough consensus on the direction here, but glad we talked it through. Let's close :)

@domenic domenic closed this as completed Sep 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

6 participants