flutter中的future是什么?

Flutter中的Future是一个异步操作,它表示一个可能在未来完成的任务。当您需要进行一些耗时的操作时,例如从服务器获取数据或者读取本地存储的文件,这些任务可能需要一些时间才能完成。如果在同步模式下执行这些操作,应用程序可能会被阻塞,直到任务完成为止。但是,使用Future,您可以将这些操作放在后台执行,而不会阻塞主线程。

在Flutter中,Future对象表示一个尚未完成的任务,并且可以在任务完成后返回结果或者错误。当您需要在UI线程中执行一些异步任务时,例如从网络获取数据或者执行耗时操作,请使用Future。

以下是一个使用Future的简单示例:

Future<String> fetchUserData() async {
  // 模拟从服务器获取数据的等待时间
  await Future.delayed(Duration(seconds: 3));
  return '用户数据';
}

void main() {
  fetchUserData().then((data) {
    print(data);
  });
}

在上面的示例中,fetchUserData函数返回一个Future对象,它模拟从服务器获取用户数据的等待时间。在main函数中,我们调用fetchUserData函数并使用.then方法注册一个回调函数,当任务完成时,将打印用户数据到控制台。

当然,这只是Future的基本使用方法。

关于更高级的Future API,Flutter提供了一些用于处理并发任务、错误处理、取消任务等常见情况的API,包括Future.wait、Future.any、Future.catchError、Future.whenComplete等。

1. Future.wait

Future.wait接受一个Future对象列表作为参数,返回一个新的Future对象,它会在所有给定的Future对象都完成之后完成。如果有任何一个Future对象失败了,新的Future对象将会失败并返回第一个失败的Future对象的错误。

以下是一个使用Future.wait的示例:

void main() async {
  List<Future> futures = [
    Future.delayed(Duration(seconds: 2), () => '数据1'),
    Future.delayed(Duration(seconds: 3), () => '数据2'),
    Future.delayed(Duration(seconds: 1), () => '数据3'),
  ];
  
  var results = await Future.wait(futures);
  print(results);
}

在上面的示例中,我们创建了一个包含三个Future对象的列表,每个Future对象都会在不同的时间返回一个字符串。我们使用Future.wait将它们组合在一起,并等待它们全部完成。在所有Future对象都完成之后,我们将它们的结果打印到控制台。

2. Future.any

Future.any接受一个Future对象列表作为参数,返回一个新的Future对象,它会在给定的Future对象中有任何一个完成时完成。返回的Future对象将会返回第一个完成的Future对象的结果。

以下是一个使用Future.any的示例:

void main() async {
  List<Future> futures = [
    Future.delayed(Duration(seconds: 2), () => '数据1'),
    Future.delayed(Duration(seconds: 3), () => '数据2'),
    Future.delayed(Duration(seconds: 1), () => '数据3'),
  ];
  
  var result = await Future.any(futures);
  print(result);
}

在上面的示例中,我们使用Future.any等待给定的Future对象中的任何一个完成。由于第三个Future对象完成的时间最短,所以返回的结果将会是“数据3”。

3. Future.catchError

Future.catchError是一个Future对象的实例方法,用于捕获Future对象中的错误。当Future对象失败时,它将会调用该方法并传递错误对象作为参数。在Future.catchError方法中,您可以处理错误、恢复错误状态或者重新抛出错误以便其他代码能够捕获它。

以下是一个使用Future.catchError的示例:

void main() async {
  try {
    var result = await Future.delayed(Duration(seconds: 2), () {
      throw Exception('发生错误');
    });
    print(result);
  } catch (e) {
    print('发生错误:$e');
  }
}

在上面的示例中,我们使用Future.delayed模拟一个可能会失败的异步任务,并在其中抛出一个异常。在main函数中,我们使用try-catch语句捕获错误并打印错误消息。

4. Future.whenComplete

Future.whenComplete是一个Future对象的实例方法,用于注册一个回调函数,当Future对象完成时,无论成功还是失败,都会执行该回调函数。

以下是一个使用Future.whenComplete的示例:

void main() async {
  try {
    var result = await Future.delayed(Duration(seconds: 2), () => '数据');
    print(result);
  } catch (e) {
    print('发生错误:$e');
  } finally {
    print('任务完成');
  }
}

在上面的示例中,我们使用Future.delayed模拟一个异步任务,并使用try-catch语句捕获错误。在finally中,我们注册了一个回调函数,当Future对象完成时,无论成功还是失败,都会执行该函数并打印“任务完成”消息。

5. Future.timeout

Future.timeout是一个Future对象的实例方法,用于设置一个超时时间,如果Future对象在超时时间内没有完成,将会失败并抛出TimeoutException异常。

以下是一个使用Future.timeout的示例:

void main() async {
  try {
    var result = await Future.delayed(Duration(seconds: 3), () => '数据');
    print(result);
  } catch (e) {
    print('发生错误:$e');
  }
  
  try {
    var result = await Future.delayed(Duration(seconds: 5), () => '数据').timeout(Duration(seconds: 2));
    print(result);
  } on TimeoutException catch (e) {
    print('超时错误:$e');
  } catch (e) {
    print('发生错误:$e');
  }
}

在上面的示例中,我们使用Future.delayed模拟一个可能会超时的异步任务。在第一个try-catch块中,我们等待3秒钟以确保任务完成。在第二个try-catch块中,我们使用timeout方法将超时时间设置为2秒钟。由于任务需要5秒钟才能完成,因此timeout方法将会抛出TimeoutException异常,并在catch块中打印超时错误消息。

6. Future.retry

Future.retry是一个函数,它接受一个返回Future对象的函数和一个可选的重试次数参数。它会一直尝试执行该函数,直到函数返回一个完成的Future对象或者达到重试次数上限为止。

以下是一个使用Future.retry的示例:

void main() async {
  var retryCount = 0;
  Future<String> fetchData() async {
    await Future.delayed(Duration(seconds: 1));
    if (retryCount < 3) {
      retryCount++;
      throw Exception('发生错误');
    }
    return '数据';
  }
  
  var result = await Future.retry(fetchData, 3);
  print(result);
}

在上面的示例中,我们使用Future.delayed模拟一个可能会失败的异步任务。在fetchData函数中,我们使用一个计数器来记录重试次数,并在前三次调用中抛出一个异常。在main函数中,我们使用Future.retry函数将fetchData函数传递给它,并设置最大重试次数为3。当fetchData函数成功执行后,它将返回数据并打印到控制台。

7. Future.doWhile

Future.doWhile是一个函数,它接受一个返回Future对象的函数,并反复执行该函数直到函数返回一个不满足条件的Future对象。

以下是一个使用Future.doWhile的示例:

void main() async {
  var count = 0;
  Future<String> fetchData() async {
    await Future.delayed(Duration(seconds: 1));
    count++;
    return '数据 $count';
  }
  
  await Future.doWhile(() async {
    var result = await fetchData();
    print(result);
    return count < 3;
  });
}

在上面的示例中,我们使用Future.delayed模拟一个异步任务,并定义fetchData函数来返回一个包含计数器值的字符串。在main函数中,我们使用Future.doWhile函数来反复执行fetchData函数直到计数器的值大于或等于3。在每个迭代中,我们打印计数器的值和fetchData函数返回的字符串。

8. Stream

Stream是一个异步数据序列,它可以用来处理大量的异步数据。Stream可以看做是一个生产者-消费者模型,它可以接受异步事件并将它们发送给监听器。

以下是一个使用Stream的示例:

void main() async {
  var controller = StreamController<String>();
  controller.add('数据1');
  controller.add('数据2');
  controller.add('数据3');
  controller.close();
  
  await for (var data in controller.stream) {
    print(data);
  }
}

在上面的示例中,我们创建了一个StreamController对象,并使用add方法将三个数据添加到Stream中。在添加数据后,我们使用close方法关闭Stream。在main函数中,我们使用异步for循环来监听Stream中的数据,并将它们打印到控制台。

9. Stream.transform

Stream.transform是一个函数,它可以转换Stream中的数据。它接受一个StreamTransformer对象作为参数,该对象定义了如何转换Stream中的数据。

以下是一个使用Stream.transform的示例:

void main() async {
  var controller = StreamController<int>();
  controller.add(1);
  controller.add(2);
  controller.add(3);
  controller.close();
  
  controller.stream.transform(StreamTransformer<int, String>.fromHandlers(
    handleData: (data, sink) {
      sink.add('数据 $data');
    },
    handleError: (error, stackTrace, sink) {
      sink.addError('发生错误:$error');
    },
    handleDone: (sink) {
      sink.close();
    },
  )).listen(print);
}

在上面的示例中,我们创建了一个StreamController对象,并使用add方法将三个整数添加到Stream中。在添加数据后,我们使用close方法关闭Stream。在main函数中,我们使用transform方法将Stream中的整数转换为字符串,并使用fromHandlers方法定义如何转换数据。在handleData函数中,我们将整数转换为字符串并添加到输出流中。在handleError函数中,我们将错误消息转换为字符串并添加到输出流中。在handleDone函数中,我们关闭输出流。最后,我们使用listen方法监听输出流中的数据,并将它们打印到控制台。

10. Stream.asyncMap

Stream.asyncMap是一个函数,它可以将Stream中的数据异步转换成其他类型的数据。它接受一个异步转换函数作为参数,并返回一个新的Stream对象。

以下是一个使用Stream.asyncMap的示例:

void main() async {
  var controller = StreamController<int>();
  controller.add(1);
  controller.add(2);
  controller.add(3);
  controller.close();
  
  controller.stream.asyncMap((data) async {
    return '数据 $data';
  }).listen(print);
}

在上面的示例中,我们创建了一个StreamController对象,并使用add方法将三个整数添加到Stream中。在添加数据后,我们使用close方法关闭Stream。在main函数中,我们使用asyncMap方法将Stream中的整数异步转换为字符串。在异步转换函数中,我们将整数转换为字符串并返回一个Future对象。最后,我们使用listen方法监听新的Stream对象中的数据,并将它们打印到控制台。

希望这些示例能够帮助您更好地理解并使用Flutter中的高级Future API。

11. StreamController

StreamController是一个用于创建和管理Stream的类。它允许您通过add、addError和close方法将事件添加到Stream中,并提供了许多用于控制Stream的方法。

以下是一个使用StreamController的示例:

void main() async {
  var controller = StreamController<int>();
  controller.stream.listen((data) {
    print('收到数据:$data');
  });
  
  controller.add(1);
  controller.add(2);
  controller.add(3);
  
  await Future.delayed(Duration(seconds: 1));
  
  controller.add(4);
  controller.addError('发生错误');
  controller.add(5);
  
  await Future.delayed(Duration(seconds: 1));
  
  controller.close();
}

在上面的示例中,我们创建了一个StreamController对象,并使用add方法将三个整数添加到Stream中。在添加数据后,我们使用listen方法注册一个回调函数,以便在接收到数据时打印它们。在1秒钟后,我们使用add方法添加第四个整数和一个错误事件。在添加数据和错误事件后,我们等待1秒钟,然后使用close方法关闭Stream。

12. Stream.periodic

Stream.periodic是一个函数,它可以创建一个在指定时间间隔内发出事件的Stream。

以下是一个使用Stream.periodic的示例:

void main() async {
  Stream.periodic(Duration(seconds: 1), (count) {
    return '数据 $count';
  }).take(5).listen(print);
}

在上面的示例中,我们使用Stream.periodic创建一个每秒钟发出一个字符串的Stream。在创建Stream后,我们使用take方法将前五个事件筛选出来,并使用listen方法打印它们到控制台。

13. Stream.fromIterable

Stream.fromIterable是一个函数,它可以将一个Iterable对象转换为Stream。

以下是一个使用Stream.fromIterable的示例:

void main() async {
  var data = [1, 2, 3];
  Stream.fromIterable(data).listen((data) {
    print('收到数据:$data')

14. Stream.where

Stream.where是一个函数,它可以根据给定的条件过滤Stream中的事件。它接受一个谓词函数作为参数,该函数返回一个布尔值,用于决定是否保留事件。

以下是一个使用Stream.where的示例:

void main() async {
  var controller = StreamController<int>();
  controller.stream.where((data) => data % 2 == 0).listen((data) {
    print('收到偶数:$data');
  });
  
  controller.add(1);
  controller.add(2);
  controller.add(3);
  controller.add(4);
  
  await Future.delayed(Duration(seconds: 1));
  
  controller.close();
}

在上面的示例中,我们创建了一个StreamController对象,并使用where方法过滤只保留偶数事件。在添加数据后,我们使用listen方法注册一个回调函数,以便在接收到偶数事件时打印它们。在1秒钟后,我们使用close方法关闭Stream。

15. Stream.expand

Stream.expand是一个函数,它可以将Stream中的每个事件转换为一个Stream,并将这些Stream中的所有事件组合成一个单独的Stream。

以下是一个使用Stream.expand的示例:

void main() async {
  var controller = StreamController<List<int>>();
  controller.stream.expand((data) => data).listen((data) {
    print('收到数据:$data');
  });
  
  controller.add([1, 2, 3]);
  controller.add([4, 5, 6]);
  
  await Future.delayed(Duration(seconds: 1));
  
  controller.close();
}

在上面的示例中,我们创建了一个StreamController对象,并使用expand方法将每个包含整数列表的事件转换为一个整数Stream。在添加数据后,我们使用listen方法注册一个回调函数,以便在接收到数据时打印它们。在1秒钟后,我们使用close方法关闭Stream。

希望这些示例能够帮助您更好地理解并使用Flutter中的高级Future API。

猜你喜欢

转载自blog.csdn.net/qq_28563283/article/details/130349439