Async & Futures

Master asynchronous programming with Futures and async/await

Asynchronous Programming in Dart


What is Asynchronous Programming?


Asynchronous programming allows your code to perform long-running tasks (like network requests or file operations) without blocking the main thread.


Synchronous vs Asynchronous


Synchronous

Code runs line-by-line. Each operation must complete before the next starts.


``dar

void main() {

print('Start');

fetchData(); // Waits for this to complete

print('End');

}


void fetchData() {

// Simulated delay

sleep(Duration(seconds: 2));

print('Data fetched');

}

`

Output:

`

Start

Data fetched (after 2 seconds)

End

`

Asynchronous

Code can continue running while waiting for long operations.


``dar

void main() async {

print('Start');

await fetchData(); // Doesn't block

print('End');

}


Future fetchData() async {

await Future.delayed(Duration(seconds: 2));

print('Data fetched');

}

`
Cell2Dart
// Synchronous function void loadData() { print('Loading...'); // Simulated work print('Data loaded'); } // Future returns a value that will be available later class DataLoader { String status = 'idle'; String fetchData() { status = 'loading'; print('Fetching data...'); // Simulate work status = 'loaded'; print('Data fetched'); return 'Success'; } } DataLoader loader = DataLoader(); String result = loader.fetchData(); print('Result: $result');

Future


A Future represents a potential value (or error) that will be available at some point in the future.


Future States


**Pending**: Operation in progress

  • Operation hasn't completed yet

  • **Completed Successfully**:

  • Operation finished with a value
  • Can access the result

  • **Completed with Error**:

  • Operation failed
  • Contains an exception

  • Async/Await Keywords


    async

    Marks a function as asynchronous. Must return a Future.


    ``dar

    Future getMessage() async {

    return 'Hello from the future!';

    }

    `

    await

    Pauses execution until a Future completes. Only works in async functions.


    ``dar

    Future main() async {

    String message = await getMessage();

    print(message);

    }

    `
    Cell4Dart
    // Future example class APICall { String endpoint = ''; APICall({required this.endpoint}); void fetch() { print('Fetching from: $endpoint'); print('Status: Loading...'); // Simulate network delay print('Status: Complete'); print('Data received'); } } APICall api = APICall(endpoint: 'api.example.com'); api.fetch();

    Handling Futures


    Using then()

    Execute code when Future completes.


    ``dar

    Future getData() {

    return Future.delayed(

    Duration(seconds: 1),

    () => 'Data loaded'

    );

    }


    void main() {

    getData().then((data) {

    print(data);

    });

    }

    `

    Using catchError()

    Handle errors that occur in Futures.


    ``dar

    getData().then((data) {

    print(data);

    }).catchError((error) {

    print('Error: $error');

    });

    `

    Using try-catch with await

    Modern approach for error handling.


    ``dar

    void main() async {

    try {

    String data = await getData();

    print(data);

    } catch (error) {

    print('Error: $error');

    }

    }

    `
    Cell6Dart
    // Error handling example class FileReader { String fileName = ''; bool fileExists = true; FileReader({required this.fileName}); String readFile() { if (!fileExists) { throw Exception('File not found'); } return 'File contents of $fileName'; } } // Read file try { FileReader reader = FileReader(fileName: 'data.txt'); String content = reader.readFile(); print(content); } catch (error) { print('Error reading file: $error'); }

    Common Async Patterns


    Chaining Multiple Async Operations


    ``dar

    void main() async {

    // Operation 1

    var data1 = await fetchData1();

    print('Got $data1');


    // Operation 2 (depends on data1)

    var data2 = await fetchData2(data1);

    print('Got $data2');

    }

    `

    Parallel Async Operations


    ``dar

    Future main() async {

    // Execute all at the same time

    var results = await Future.wait([

    fetchData1(),

    fetchData2(),

    fetchData3(),

    ]);


    print('All done: $results');

    }

    `

    When to Use Async


  • **Network requests**: Fetching data from servers
  • **File operations**: Reading/writing files
  • **Database queries**: Querying data
  • **Timers**: Delayed operations
  • **User input**: Waiting for user actions

  • Async prevents your app from freezing while waiting!

    Run code to see async operations in action