prefer-async-await

Same as prefer-async-await in Dart Code Metrics

Group
Style
Path
lint/style/prefer-async-await
Default
Off, opt in
Origin
Dart Code Metrics
Rule
316 of 512

Flags .then(...) future chains that should use async/await.

Chaining callbacks with Future.then nests logic inside closures and scatters error handling across onError/catchError, whereas async/await lets asynchronous code read top-to-bottom with ordinary try/catch. Function literals passed to a chain are treated as delayed scopes and remain opaque.

Matching is currently syntactic on the then name. Resolver-backed Future identity is required before unrelated user-defined then methods can be excluded reliably.

Invalid

example.dartdart
// Bad: using .then() chains instead of async/await
Future<String> getData() {
  return fetch().then((data) {
    return process(data);
  });
}

void processUser() {
  getUserId().then((id) {
    print(id);
  });
}

Future<int> compute() {
  return loadData().then((d) => transform(d)).catchError((e) {
    print('Error: $e');
    return 0;
  });
}

class Api {
  Future<String> fetchName() {
    return http.get(url).then((response) => response.body);
  }
}

void refresh() {
  reload().then((_) => notifyListeners());
}

void withLocalFunction() {
  void body() {
    reload().then((_) => notifyListeners());
  }
  body();
}

void restoredAfterArrow(Future<int> future) {
  Future<int> arrow() => future.then((value) => value);
  final callback = () {
    future.then((value) => value);
  };
  future.then((value) => value);
  print(callback);
}
Prefer `async` and `await` over `.then()` chains.
2Future<String> getData() {
3 return fetch().then((data) {
Prefer `async` and `await` over `.then()` chains.
8void processUser() {
9 getUserId().then((id) {
Prefer `async` and `await` over `.then()` chains.
14Future<int> compute() {
15 return loadData().then((d) => transform(d)).catchError((e) {
Prefer `async` and `await` over `.then()` chains.
22 Future<String> fetchName() {
23 return http.get(url).then((response) => response.body);
Prefer `async` and `await` over `.then()` chains.
27void refresh() {
28 reload().then((_) => notifyListeners());
Prefer `async` and `await` over `.then()` chains.
32 void body() {
33 reload().then((_) => notifyListeners());
Prefer `async` and `await` over `.then()` chains.
42 };
43 future.then((value) => value);

Valid

example.dartdart
// Good: using async/await instead of .then() chains
Future<String> getData() async {
  final data = await fetch();
  return process(data);
}

void processUser() async {
  final id = await getUserId();
  print(id);
}

Future<int> compute() async {
  try {
    final d = await loadData();
    return transform(d);
  } catch (e) {
    print('Error: $e');
    return 0;
  }
}

class Api {
  Future<String> fetchName() async {
    final response = await http.get(url);
    return response.body;
  }
}

// OK: .then() with simple arrow function
Future<String> simpleFetch() => fetch().then((d) => d);

// OK: arrow-bodied local function is a delayed scope, same as a top-level arrow body.
void withArrowLocalFunction() {
  void body() => reload().then((_) => notifyListeners());
  body();
}

Configure prefer-async-await

Set its severity in falcon.json. See the configuration guide.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "style": {
        "prefer-async-await": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/style/prefer-async-await: <reason>