YouTip LogoYouTip

Dart Async

Asynchronous programming is one of the most core capabilities in modern application development. Whether it's network requests, file I/O, or database operations, all require asynchronous processing to avoid blocking the main thread. This chapter introduces the concept of Future, async/await syntax, and how to handle asynchronous errors. * * * ## Why Asynchronous Programming is Needed First, understand the difference between synchronous and asynchronous. Synchronous code executes line by line in order, and the next line won't start until the previous line completes. If an operation needs to wait (such as a network request), the entire program will freeze. ## Example Compare the execution effects of synchronous and asynchronous code: // Simulate a time-consuming operation String fetchDataSync(){ // Synchronous code: assume this takes 2 seconds to wait // During these 2 seconds, the entire program cannot do anything sleep(Duration(seconds:2));// Blocking wait return'Data fetched'; } // Asynchronous version: does not block the main thread Future fetchDataAsync() async { // Asynchronous wait: during these 2 seconds, the program can continue executing other tasks await Future.delayed(Duration(seconds:2)); return'Data fetched'; } void main() async { print('Start synchronous data fetch...'); var syncResult = fetchDataSync(); print('Synchronous result: $syncResult'); print('(Note: program was blocked during sync)'); print(' Start asynchronous data fetch...'); print('After initiating request, program continues executing other tasks...'); var asyncResult = await fetchDataAsync(); print('Asynchronous result: $asyncResult'); print('(Program was not blocked during async)'); } Start synchronous data fetch...Synchronous result: Data fetched(Note: program was blocked during sync)Start asynchronous data fetch...After initiating request, program continues executing other tasks...Asynchronous result: Data fetched(Program was not blocked during async) > In Dart, all I/O operations (files, networks, databases) should use asynchronous methods. Synchronous I/O blocks the entire Isolate, which causes UI freezing in Flutter applications. * * * ## Concept of Future Future represents a value that "will complete at some point in the future". It's like a promise: I don't have the result now, but I will definitely give you a value of type T in the future (or an error). Future has three states: | State | Description | | --- | --- | | Uncompleted | Asynchronous operation is still in progress | | Completed with data | Operation succeeded, Future carries the result value | | Completed with error | Operation failed, Future carries the error information | ## Example Create and use Future: void main(){ print('Program starts'); // Create a Future Future future = Future((){ // This function will execute at some point in the future return'TUTORIAL async result'; }); print('Future created, but not yet completed'); // Register callback: execute when Future completes future.then((result){ print('Received result: $result'); }); print('Program continues...'); } Program startsFuture created, but not yet completedProgram continues...Received result: TUTORIAL async result Note the order of output: "Program continues" is printed first, then "Received result". This shows that Future's callback is executed asynchronously and does not block subsequent code. * * * ## async / await Syntax async and await are the core syntax for handling asynchronous operations in Dart. async marks a function as asynchronous, and await waits for a Future to complete and gets its result. ## Example // async keyword marks function as asynchronous // Asynchronous function's return type must be Future Future fetchUserName(int id) async { // await waits for Future to complete and gets its value // During wait, current function pauses execution, but does not block other code await Future.delayed(Duration(seconds:1)); return'User $id'; } Future fetchUserAge(int id) async { await Future.delayed(Duration(milliseconds:500)); return 20+ id; } // Execute multiple asynchronous operations sequentially Future printUserInfo(int id) async { print('Start fetching user info...'); // Wait one by one: get name first, then get age var name = await fetchUserName(id); print('Got name: $name'); var age = await fetchUserAge(id); print('Got age: $age'); print('TUTORIAL user: $name, age: $age'); } // Execute multiple asynchronous operations concurrently Future printUserInfoParallel(int id) async { print('Start fetching user info concurrently...'); // Initiate two requests at the same time, not waiting for each other var nameFuture = fetchUserName(id); var ageFuture = fetchUserAge(id); // Wait for both requests to complete var results = await Future.wait([nameFuture, ageFuture]); var name = resultsas String; var age = resultsas int; print('TUTORIAL user (concurrent): $name, age: $age'); } void main() async { // Sequential execution (total time β‰ˆ 1s + 0.5s = 1.5s) await printUserInfo(1); print('---'); // Concurrent execution (total time β‰ˆ max(1s, 0.5s) = 1s) await printUserInfoParallel(2); } Start fetching user info...Got name: User1Got age: 21 TUTORIAL user: User1, age: 21---Start fetching user info concurrently... TUTORIAL user (concurrent): User2, age: 22 > If multiple asynchronous operations have no dependencies between them, use Future.wait to let them execute concurrently instead of awaiting one by one. This can significantly improve performanceβ€”the total time equals the slowest operation, not the sum of all operations. ### Core Rules of async/await | Rule | Description | | --- | --- | | async function returns Future | Even if function returns T, after async it will be automatically wrapped as Future | | await can only be used in async functions | Regular functions cannot use await | | await pauses current function | But does not block execution of other code | | await gets Future's result | If Future has error, await will throw exception | * * * ## then / catchError Chained Calls Besides async/await, Dart also supports using then() and catchError() for chained calls. This is the traditional Promise-stylesyntax. ## Example // Function simulating network request Future fetchData(String url){ return Future.delayed(Duration(seconds:1),(){ if(url.isEmpty){ throw Exception('URL cannot be empty'); } return'Data from $url'; }); } void main(){ print('Start request...'); // then / catchError chained calls fetchData('https://example.com/api') .then((data){ // Request successful print('Got data: $data'); return'Processed: $data';// Return value will be passed to next then }) .then((processed){ // Process return value from previous then print(processed); }) .catchError((error){ // Catch any error in the chain uniformly print('Request error: $error'); }) .whenComplete((){ // Execute whether successful or failed (similar to finally) print('Request ended (success
← Dart IsolatesDart Packages And Libraries β†’