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

Consuming immediately available async results in one frame #113763

Open
blaugold opened this issue Oct 20, 2022 · 1 comment
Open

Consuming immediately available async results in one frame #113763

blaugold opened this issue Oct 20, 2022 · 1 comment
Labels
c: proposal A detailed proposal for a change to Flutter dependency: dart Dart team may need to help us framework flutter/packages/flutter repository. See also f: labels. P3 Issues that are less important to the Flutter project team-framework Owned by Framework team triaged-framework Triaged by Framework team

Comments

@blaugold
Copy link
Contributor

blaugold commented Oct 20, 2022

This issue is about the problem of consuming immediately available results from a Future within one frame.

A typical use case is a data API that caches results of previous requests.

Sometimes a result can be resolved synchronously (e.g. from a cache) or asynchronously (e.g. from the network). The producer of such a result can create and hand out a Future synchronously and asynchronously. Only async code can consume a Future, though.

Code that runs as part of building widgets must be synchronous and cannot consume an immediately available result that is contained in a Future in the same frame that awaits the Future. The result is only accessible in the next frame, creating an unnecessary delay or worse a flicker in the UI.

SynchronousFuture

SynchronousFuture calls its then callback synchronously, and thus allows its result to be consumed synchronously.

The name SynchronousFuture is somewhat distracting. We don’t necessarily care about the result being available synchronously. We care about the result being visible in the same frame.

Problems with SynchronousFuture

Possible solutions

Custom result type

A custom result type can expose an API to access the result as soon as it is available. The downside of this solution is that it excludes all the useful affordances available for working with async computations such as await, standard library APIs and packages that build on async Dart APIs.

Multiple build/layout phases per frame

After building dirty widgets, allow microtasks that were scheduled to run, and build widgets that were dirtied by those microtasks. This needs to be repeated in a loop so that all widgets (including those that were rebuilt in another than the first build phase) can consume immediately available results.

In a loop:

  • Build dirty elements
  • Layout dirty render objects
  • If microtask queue is empty
    • Break the loop
  • Drain microtask queue

Upsides

  • Allows results that are immediately available to be used in the same frame.
  • Does not require a change in Dart.
  • Adheres to specified semantics of async Dart APIs.
  • Composing async results with await and the standard library works as expected.
  • No need for APIs to return FutureOr / other custom result type.

Downsides

  • Some widgets will be built twice in the same frame.
  • Infinite loops can be induced accidentally.
    • build → schedule microtask → setState → build
  • Enforcing that the build of one widget does not cause the build of a widget above it gets harder.

Change Dart to somehow support synchronous Futures

As discussed in the two issues above, there are lots of problems with making that work.

@darshankawar darshankawar added the in triage Presently being triaged by the triage team label Oct 21, 2022
@darshankawar
Copy link
Member

Thanks for the detailed report. Treating this as a potential proposal and for further insights from the team.

@darshankawar darshankawar added framework flutter/packages/flutter repository. See also f: labels. dependency: dart Dart team may need to help us c: proposal A detailed proposal for a change to Flutter and removed in triage Presently being triaged by the triage team labels Oct 21, 2022
@goderbauer goderbauer added the P3 Issues that are less important to the Flutter project label Oct 25, 2022
@flutter-triage-bot flutter-triage-bot bot added team-framework Owned by Framework team triaged-framework Triaged by Framework team labels Jul 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: proposal A detailed proposal for a change to Flutter dependency: dart Dart team may need to help us framework flutter/packages/flutter repository. See also f: labels. P3 Issues that are less important to the Flutter project team-framework Owned by Framework team triaged-framework Triaged by Framework team
Projects
None yet
Development

No branches or pull requests

3 participants