dart-lang / dart-lang/language

Asynchronous Constructors

Open
#782 9 comments 60 reactions 0 assignees View on GitHub
request
Dominant language
TeX
Stars
2.9k
Forks
239
Avg merge
2d 18h
Merged PRs (30d)
14

Description

Users, especially new users, keep running into situations where they would like to create objects where part of the initialziation is asynchronous. They then ask for asynchronous constructors. The answer has, so far, been: Use a static factory function instead.
(https://github.com/dart-lang/sdk/issues/23115, https://stackoverflow.com/questions/38933801/calling-an-async-method-from-component-constructor-in-dart, )

However, there isn't anything inherently impossible about asynchronous constructors.

### Generative constructors

Consider the following:
```dart
class MyClass {
final T value1;
final T value2;
T _sumCache;
async MyClass.fromFutures(FutureOr value1, FutureOr value2)
: value1 = await value1, value2 = await value2 {
_sumCache = value1 + value2 + await somethingMore;
}
}
```
The could define an *asynchronous generative constructor*. It can be redirecting only if it redirects to another asynchronous generative constructor.

Such a constructor has an implicit return type of `Future>`, and it allows using `await` in both the initializer list and the constructor body. The `async` is written up front because it modifies both the implicit return type and the initializer list, not just the body as for normal `async` functions.

It can only be used as the `super`-constructor of another asynchronous generative constructor.

As usual, the instance is not available to anyone before the body starts running, and at that point the object state is sound. You can leak the object if you want to, but if not, the caller only gets it when the body completes and the returned future is completed with that instance.

### Factory constructors
The same way, we can introduce `async factory MyClass(...)` for an asynchronous factory constructor. It can either redirect to another async constructor or it can have a body which can then user `await`.

The real question here is whether it's worth doing since a static factory function *works*. It has to be backed by a generative constructor, though, which makes it more work to implement than if you could combine everything into just the constructor.
It is a recurring issue for new users, and as such a stumbling block. It's typically solved when the user goes to stackoverflow or our forums, but it's still a negative first/early impression.

Contributor guide

Open the contributing guide

Research direction

Start with the proposed asynchronous generative and factory constructor semantics in this issue, then review the linked Dart SDK issue and Stack Overflow discussion for existing context. There are no implementation files or tests named; done would require a decided language-design direction on whether asynchronous constructors should be added and how their rules work.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.