Flutter 中 Async

89 阅读3分钟

在 Flutter 中,处理异步操作是开发应用程序的一个重要方面。Flutter 提供了多种方法来处理异步操作,包括使用 FutureasyncawaitStream 等。理解这些概念和如何使用它们对于构建响应迅速的应用程序至关重要。

异步编程基础

1. Future

Future 是表示异步计算结果的对象。一个 Future 表示将来某个时刻会提供的值或错误。

2. asyncawait

async 关键字用于标记一个函数为异步函数,await 关键字用于暂停异步函数的执行,直到 Future 完成并返回结果。

3. Stream

Stream 用于表示一系列异步事件或数据,可以通过监听这些事件来处理数据流。

异步操作示例

以下是一些常见的异步操作示例代码。

示例 1:使用 Futureawait

这是一个简单的示例,演示如何使用 Futureawait 来处理异步操作,例如从网络加载数据。

import 'package:flutter/material.dart';
import 'dart:async'; // For Future

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Async Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _data = 'Loading...';

  @override
  void initState() {
    super.initState();
    _loadData();
  }

  Future<void> _loadData() async {
    String data = await fetchData();
    setState(() {
      _data = data;
    });
  }

  Future<String> fetchData() async {
    // Simulate a network call
    await Future.delayed(Duration(seconds: 2));
    return 'Data loaded';
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Async Demo'),
      ),
      body: Center(
        child: Text(_data),
      ),
    );
  }
}

解释

  1. initState:初始化状态时调用 _loadData 方法。
  2. _loadData:异步方法,等待 fetchData 方法返回数据,然后更新状态。
  3. fetchData:模拟一个网络调用,延迟 2 秒后返回数据。

示例 2:使用 FutureBuilder

FutureBuilder 是一个 Flutter 小部件,用于构建依赖异步数据的 UI。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FutureBuilder Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  Future<String> fetchData() async {
    // Simulate a network call
    await Future.delayed(Duration(seconds: 2));
    return 'Data loaded';
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('FutureBuilder Demo'),
      ),
      body: Center(
        child: FutureBuilder<String>(
          future: fetchData(),
          builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return CircularProgressIndicator();
            } else if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            } else {
              return Text('Result: ${snapshot.data}');
            }
          },
        ),
      ),
    );
  }
}

解释

  1. fetchData:异步方法,模拟网络调用。
  2. FutureBuilder:根据 fetchData 返回的 Future 构建 UI。根据 connectionState 展示不同的状态,如加载中、错误或结果。

示例 3:使用 StreamBuilder

StreamBuilder 是一个 Flutter 小部件,用于构建依赖异步数据流的 UI。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'StreamBuilder Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  Stream<int> counterStream() async* {
    for (int i = 0; i < 10; i++) {
      await Future.delayed(Duration(seconds: 1));
      yield i;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('StreamBuilder Demo'),
      ),
      body: Center(
        child: StreamBuilder<int>(
          stream: counterStream(),
          builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return CircularProgressIndicator();
            } else if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            } else if (snapshot.hasData) {
              return Text('Counter: ${snapshot.data}');
            } else {
              return Text('Stream completed');
            }
          },
        ),
      ),
    );
  }
}

解释

  1. counterStream:生成一个异步流,每秒递增一个整数。
  2. StreamBuilder:根据 counterStream 返回的流构建 UI。根据 connectionState 展示不同的状态,如加载中、错误、数据或流结束。

总结

在 Flutter 中处理异步操作非常重要,理解 FutureasyncawaitStream 及其相应的构建器(如 FutureBuilderStreamBuilder)能够帮助你构建响应迅速、用户体验良好的应用程序。上述示例展示了如何在实际应用中使用这些异步工具。通过这些示例,你可以开始在你的 Flutter 应用中使用异步编程来处理各种异步操作,如网络请求、计时器等。