Dart async expert
Skill almasumdev/awesome-flutter-agent-skills/.github/skills/concurrency_and_networking/dart-async-expert
Curated agent skills, conventions, and workflows for building Flutter apps with AI coding agents.
npx -y skills add almasumdev/awesome-flutter-agent-skills --skill dart-async-expertAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Review and fix Dart async code — Futures, async/await, error handling, cancellation, and isolates. Use this when auditing asynchronous code for correctness and performance.
SKILL.md
3.0 KB, as published. Nobody here has run it
Dart Async Expert
Instructions
Write async code that is predictable, testable, and does not block the UI thread.
1. Prefer async/await Over .then
// Good
final user = await repo.fetchUser(id);
final prefs = await repo.fetchPrefs(user.id);
// Avoid chained thens — harder to read, harder to handle errors.
2. Run Independent Work in Parallel
If two futures do not depend on each other, launch them concurrently:
final (user, prefs) = await (repo.fetchUser(id), repo.fetchPrefs(id)).wait; // Dart 3
// or
final results = await Future.wait([repo.fetchUser(id), repo.fetchPrefs(id)]);
3. Error Handling
- Use
try/on TypedException/catch. Do not swallow errors with barecatch (_). - Convert low-level exceptions to domain ones at the repository boundary.
Future.wait([...])fails fast on the first error — useeagerError: falseif you need all errors collected.
4. Cancellation
Dart Future is not cancellable by itself. Patterns:
- Dio: pass a
CancelTokenand callcancelToken.cancel()indispose. - Streams: keep the
StreamSubscriptionand.cancel()it. - Custom: pass a boolean/
Completer-based signal and check it atawaitpoints.
5. Don't Block the Event Loop
- CPU-bound work (parsing large JSON, crypto, image decode) must run in an isolate. Use
Isolate.run(() => expensive())(Dart 3) orcompute(fn, arg). - A
Futuredoes not mean "other thread" — it still runs on the UI isolate unless you explicitly spawn one.
6. Timeouts
final response = await api.fetch().timeout(
const Duration(seconds: 10),
onTimeout: () => throw TimeoutException('fetch'),
);
Prefer per-call timeouts over a single global one — failures are easier to attribute.
7. Microtasks vs Timers
scheduleMicrotaskruns before any further I/O. Use sparingly.Timer,Future.delayed(Duration.zero)yield to the event loop. Use to avoid "setState during build" when unavoidable.
8. Common Pitfalls
- Forgetting
await— the future runs, but errors become unhandled and the caller continues immediately. Enableunawaited_futureslint. asyncinsideinitState— wrap the body or use anunawaited(_init())call plus proper error handling.- Performing
awaitacrossBuildContextwithout checkingif (!mounted) return;afterwards. - Holding references to
BuildContextorStatein long-lived async closures → leaks.
9. Checklist
- Every
Future-returning call isawaited or explicitlyunawaited(...). - Independent calls use
.wait/Future.wait. - CPU-bound work runs in an isolate.
-
BuildContextis not used afterawaitwithout amountedcheck. - Cancellation paths are handled for in-flight work on
dispose.