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
// 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);
}Future<String> getData() { return fetch().then((data) {void processUser() { getUserId().then((id) {Future<int> compute() { return loadData().then((d) => transform(d)).catchError((e) { Future<String> fetchName() { return http.get(url).then((response) => response.body);void refresh() { reload().then((_) => notifyListeners()); void body() { reload().then((_) => notifyListeners()); }; future.then((value) => value);Valid
// 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.
{
"linter": {
"rules": {
"style": {
"prefer-async-await": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/style/prefer-async-await: <reason>More style rules
- prefer-async-callback
prefer_async_callbackflutterFlags the type
Future<void> Function()in favor of Flutter'sAsyncCallback. - prefer-bloc-event-suffixbloc
Enforce the package-confirmed Bloc convention.
- prefer-bloc-extensionsbloc
Prefer context.read/watch over
package:flutter_bloc's provider lookups. - prefer-bloc-state-suffixbloc
Enforce the package-confirmed Bloc convention.
- prefer-center-over-alignflutter
Prefers
Centerover anAlignwhose alignment is known to be centered. - prefer-collection-literals
prefer_collection_literalsrecommendedFlags no-argument collection constructor calls that a literal would express.
- prefer-commenting-analyzer-ignores
Require explanations for analyzer
ignore:andignore_for_file:comments. - prefer-const-constructors
prefer_const_constructorsPrefers
constwhen invoking aconstconstructor with constant arguments.