// Standalone teaching demo. Timers simulate I/O; no real API is called. Future fetchProfile() async { await Future.delayed(const Duration(milliseconds: 600)); return 'Thura'; } Future fetchAnnouncements() async { await Future.delayed(const Duration(milliseconds: 900)); return '2 announcements'; } Future> loadSequentially() async { final profile = await fetchProfile(); final announcements = await fetchAnnouncements(); return [profile, announcements]; } Future> loadConcurrently() { return Future.wait([ fetchProfile(), fetchAnnouncements(), ]); } Future main() async { for (final entry in { 'Sequential': loadSequentially, 'Concurrent': loadConcurrently, }.entries) { final stopwatch = Stopwatch()..start(); final result = await entry.value(); stopwatch.stop(); if (result.join('|') != 'Thura|2 announcements') { throw StateError('Unexpected results or input ordering'); } print('${entry.key}: ${stopwatch.elapsedMilliseconds} ms; $result'); } // Verify default wait behavior when a faster operation fails. final events = []; try { await Future.wait([ Future.delayed(const Duration(milliseconds: 100), () { events.add('slow operation completed'); return 'ok'; }), Future.delayed(const Duration(milliseconds: 20), () { events.add('fast operation failed'); throw StateError('Simulated failure'); }), ]); } on StateError { events.add('caller caught error'); } const expected = 'fast operation failed|slow operation completed|caller caught error'; if (events.join('|') != expected) throw StateError('Unexpected error timing'); print('Error path: ${events.join(' -> ')}'); }