Skip to content

"await" doesn't wait for nested future in Future<Future<void>> #52621

Closed
@DanTup

Description

@DanTup

My understanding is that if I await a function that returns a Future, if that Future completes with a Future, that would be awaited to. And that seems to happen for most examples. However, when working on some code in the analysis server today I found that wasn't happening. I think it might be related to FutureOr but any further attempt to simplify my example seem to "fix" the problem.

The smallest repro I have is this:

import 'dart:async';

import 'package:test/test.dart';

Future<void> main() async {
  var runner = WorkRunner(() async {
    await pumpEventQueue(times: 5000);
    print('DOING WORK');
  });
  await runner.run();
  print('FINISHED');
}

class WorkRunner {
  final Future<void> Function() work;

  WorkRunner(this.work);

  Future<void> run() => run2(work);

  FutureOr<T> run2<T>(
    FutureOr<T> Function() operation,
  ) async {
    return await operation();
  }
}

As far as I can tell, all futures are awaited. If I print(runner.run()) I see Future<Future<void>>. The output when run is:

FINISHED
DOING WORK

Removing async from run2 fixes the issue (as do all sorts of other small modifications). I suspect it's working as intended, but I don't understand why (and since there are no warnings, it feels easy to get wrong - I just happened to catch this with a test).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions