flutter实现异步有哪些方式?

369 阅读2分钟

在 Flutter 中,有多种方式可以实现异步编程,主要包括以下几种:

1. Futureasync/await

这是 Dart 中最常见的异步编程方式,用于处理一次性异步操作,例如网络请求、文件读取等。

  • Future:表示一个将来会完成(或失败)的异步操作,可以用 .then().catchError() 来处理结果或错误。

  • async/await:使用 async 标记一个函数,然后在函数内部使用 await 来等待 Future 完成,使得异步代码看起来像同步代码一样清晰易懂。

    dart
    复制代码
    Future<void> fetchData() async {
      try {
        var data = await http.get('https://example.com/data');
        print(data.body);
      } catch (e) {
        print("Error: $e");
      }
    }
    

2. Stream

Stream 用于处理一系列的异步事件或数据,适用于连续的数据流,例如传感器数据、用户输入事件等。Stream 既可以同步处理,也可以异步处理。

  • 单订阅 Stream:每次只能有一个监听器(listener)。
  • 广播 Stream:允许多个监听器同时订阅。

使用 await for 可以逐个处理 Stream 中的数据:

dart
复制代码
Stream<int> countStream(int to) async* {
  for (int i = 1; i <= to; i++) {
    await Future.delayed(Duration(seconds: 1));
    yield i;
  }
}

void main() async {
  await for (var value in countStream(5)) {
    print(value); // 每秒钟打印一个数字
  }
}

3. Isolate

Isolate 用于多线程处理,是 Dart 中隔离的执行环境。每个 Isolate 有自己的内存空间,无法与其他 Isolate 共享内存,只能通过消息传递通信。

Isolate 适用于需要在后台执行密集计算任务的场景,而不会阻塞主线程。

dart
复制代码
import 'dart:async';
import 'dart:isolate';

void doWork(SendPort sendPort) {
  sendPort.send("Work Done");
}

void main() async {
  final receivePort = ReceivePort();
  await Isolate.spawn(doWork, receivePort.sendPort);
  receivePort.listen((message) {
    print(message); // 输出 "Work Done"
  });
}

4. Completer

Completer 是一个更底层的工具,允许你手动控制 Future 的完成。它在一些高级场景下非常有用,比如你需要在某个非异步的回调中完成一个 Future

dart
复制代码
Future<String> fetchData() {
  final completer = Completer<String>();

  // 模拟一个异步操作,比如网络请求
  Timer(Duration(seconds: 2), () {
    completer.complete("Data fetched");
  });

  return completer.future;
}

void main() async {
  var data = await fetchData();
  print(data); // 2秒后输出 "Data fetched"
}

总结

Flutter 中异步编程主要通过 FutureStreamIsolateCompleter 等工具来实现,每种方式都有其适用的场景。选择哪种异步方式取决于你要处理的异步任务的性质,比如是一次性的操作、持续的数据流、还是需要独立的执行环境等。