Irbisa · Cheatsheet
Async & Futures
Future, async/await, then/catchError, FutureBuilder
What is a
Future, how doasyncandawaitwork, and how do you handle errors from a Future?Future<String> fetchUser(int id) async { await Future<void>.delayed(const Duration(seconds: 1)); // stands in for a network call if (id <= 0) throw ArgumentError.value(id, 'id'); return 'User #$id';}…Does
async/awaitrun your code on another thread?What does this code print, and which part of
load()runs beforemain()moves on?Future<void> load() async { print('2'); await Future<void>.delayed(Duration.zero); print('4');} void main() { print('1'); load(); print('3');}What is the difference between
.then()chaining andasync/await, and how doeswhenComplete()differ fromthen()?// then-chainFuture<Profile> loadChain(String id) { return api .user(id) .then((u) => api.profile(u.id)) .catchError((Object e) => Profile.empty());…What is
Timer/Timer.periodic, how do you cancel it, and what happens if you forget to cancel it indispose()?class _ClockState extends State<Clock> { Timer? _ticker; Timer? _debounce; DateTime _now = DateTime.now(); @override…What does
FutureBuilderdo, and why should you not create its Future insidebuild()?class ProfilePage extends StatefulWidget { const ProfilePage({super.key, required this.id}); final String id; @override State<ProfilePage> createState() => _ProfilePageState();…Why should an
asyncfunction returnFuture<void>instead ofvoid?// wrong: callers cannot wait for it or catch its errorsvoid saveDraftVoid() async { await storage.write(draft);} // right…What happens if you forget to
awaita Future, and when is fire-and-forget withunawaited()acceptable?Future<void> onSave() async { await repo.save(draft); // right: wait for what the next line depends on unawaited(analytics.track("saved").catchError(logDrop)); // fire-and-forget, errors handled // wrong: repo.save(draft); close(); // close() runs before the save finishes}Find the bug: the "All photos synced" toast appears while photos are still uploading.
Future<void> syncPhotos(List<Photo> photos) async { photos.forEach((photo) async { await api.upload(photo); await db.markSynced(photo.id); }); showToast('All ${photos.length} photos synced');}How do you run several Futures concurrently, and what happens when one of them fails?
Future<void> load(String id) async { // Same type: one list, results in the original order final pages = await Future.wait([loadPage(1), loadPage(2), loadPage(3)]); // Per-future fallback: one failure does not lose the other result final counts = await Future.wait([…How does Dart's event loop work, and what is the difference between the microtask queue and the event queue?
In what order does this code print, and why?
void main() { print('A'); Future(() => print('B')); Future.delayed(Duration.zero, () => print('C')); scheduleMicrotask(() => print('D')); Future.value(1).then((_) => print('E')); Future.sync(() => print('F')); print('G');}What is a
Completer, and when would you use one?Future<Position> currentPosition(LocationSdk sdk) { final completer = Completer<Position>(); sdk.requestOnce( onSuccess: (pos) { if (!completer.isCompleted) completer.complete(pos);…What is
FutureOr<T>and when would a function return it instead ofFuture<T>?FutureOr<User> getUser(String id) { final cached = _cache[id]; if (cached != null) return cached; // synchronous: no event-loop turn return _fetchAndCache(id); // Future<User>}…Why does
catchErrorhere never run whenidis empty, and how do you fix it?Future<User> load(String id) { if (id.isEmpty) throw ArgumentError.value(id, 'id'); return api.getUser(id);} void onTap(String id) { load(id).catchError((Object e) { log('failed: $e'); return User.guest(); });}Find the bug: when the device is offline,
loadProfilethrows instead of returning the cached profile.Future<Profile> loadProfile(String id) async { try { return api.fetchProfile(id); } on NetworkException { return cache.read(id); }}How do you add a timeout and retries to a Future?
Future<T> retry<T>( Future<T> Function() task, { int maxAttempts = 4, Duration baseDelay = const Duration(milliseconds: 500), bool Function(Object error) retryIf = _isTransient,}) async {…How do you catch all uncaught errors in a Flutter app, and why does wrapping
runApp()in try/catch not work?void main() { WidgetsFlutterBinding.ensureInitialized(); FlutterError.onError = (FlutterErrorDetails details) { FlutterError.presentError(details); // keep the console output crashReporter.recordFlutterError(details);…Dart Futures cannot be cancelled. How do you stop work the user has already navigated away from?
class _SearchState extends State<Search> { int _latest = 0; List<Hit> _hits = const []; CancelableOperation<List<Hit>>? _op; Future<void> onQueryChanged(String q) async {…You store a Future in a field and await it in a try/catch a second later, yet the app still logs an unhandled exception. Why?
class Warmup { // wrong: starts now and may fail before anyone listens final Future<Config> _config = loadConfig(); Future<void> run() async { await Future<void>.delayed(const Duration(seconds: 1));…Crash reports show a stack trace that ends at the event loop instead of the failing line. What loses the origin of an async error?
// wrong: a new throw builds a new traceFuture<void> saveLosing(Order order) async { try { await repo.save(order); } catch (e) { throw SaveFailed('$e'); // the trace now starts on this line…Dart is single-threaded, so how can two async calls still race, and how do you serialize access to a shared resource?
class TokenManager { Future<Tokens>? _refreshing; // every caller during a refresh shares one request Future<Tokens> refresh() => _refreshing ??= _doRefresh().whenComplete(() => _refreshing = null);…