Skip to content

An async function declared to return FutureOr<T> can't directly return a T #606

Open
@jamesderlin

Description

@jamesderlin

Currently declaring an async function as returning FutureOr<T> is allowed but seems misleading and useless (it's no different than returning Future<T>) except maybe in the case of overriding a method already declared to return FutureOr<T>. That is, if I have:

FutureOr<int> foo() async {
  return 42;
}

then foo() is Future<int> is true and and foo() is int is not, and the only way to extract the value is via await/then().

Motivation:

I want to have a function:

FutureOr<int> foo(bool doOptionalWork) async {
  // ... Do some preliminary work here...

  if (doOptionalWork) {
    await someAsyncOperation();
  }

  // ... Do some additional work here...
  return result;
}

with the expectation that calling foo(false) will return an int. (The intent is avoid forcing await/then() onto the caller.)

A workaround is to transform the code to avoid using async:

FutureOr<int> foo(bool doOptionalWork) {
  // ... Do some preliminary work here...

  int doAdditionalWork() {
    // ... Do some additional work here...
    return result;
  }

  if (doOptionalWork) {
    return someAsyncOperation().then((_) {
      return doAdditionalWork();
    });
  }

  return doAdditionalWork();
}

Could the compiler do such a transformation automatically?

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