1. Future的并发控制
- 并行执行: 使用
Future.wait
方法来并行执行多个Future
。例如,在一个新闻应用中,需要同时加载新闻列表和用户设置。
Future<List<dynamic>> loadData() async {
Future<List<News>> newsFuture = fetchNews();
Future<UserSettings> settingsFuture = fetchUserSettings();
List<dynamic> results = await Future.wait([newsFuture, settingsFuture]);
return results;
}
- 串行执行: 使用
async*
和yield
来串行执行Future
。比如在一个需要依次下载多个文件的场景中。
Stream<File> downloadFiles(List<String> urls) async* {
for (String url in urls) {
File file = await downloadFile(url);
yield file;
}
}
2. 缓存机制的引入
- 内存缓存: 使用
Map
来实现简单的内存缓存。假设我们有一个获取用户信息的接口,并且在短时间内可能会多次调用。
Map<String, User> userCache = {};
Future<User> getUser(String userId) async {
if (userCache.containsKey(userId)) {
return userCache[userId];
}
User user = await fetchUserFromServer(userId);
userCache[userId] = user;
return user;
}
- 持久化缓存: 使用
shared_preferences
或hive
等库进行持久化缓存。以存储用户登录信息为例,使用shared_preferences
。
import 'package:shared_preferences/shared_preferences.dart';
Future<bool> saveUserLoginInfo(String token) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.setString('user_token', token);
}
Future<String?> getUserLoginInfo() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString('user_token');
}
3. 处理数据依赖关系
- 链式调用: 如果
Future
之间存在依赖关系,可以使用链式调用。例如,在一个电商应用中,先获取商品列表,然后根据商品ID获取商品详情。
Future<ProductDetail> getProductDetail() async {
List<Product> products = await fetchProductList();
Product firstProduct = products.first;
return fetchProductDetailById(firstProduct.id);
}
- 使用
Completer
: 当需要手动控制Future
的完成时,可以使用Completer
。比如在一个需要等待多个异步操作完成后再触发某个操作的场景。
Completer<void> completer = Completer<void>();
Future<void> performComplexOperation() async {
Future<void> operation1 = performOperation1();
Future<void> operation2 = performOperation2();
Future.wait([operation1, operation2]).then((_) {
completer.complete();
});
return completer.future;
}
4. 避免资源浪费
- 取消
Future
: 使用CancelToken
或Future
的cancel
方法(如果支持)来取消未完成的Future
。例如,在一个搜索功能中,用户频繁输入搜索关键词,前一个搜索请求如果还未完成,可以取消。
import 'package:http/http.dart' as http;
import 'package:http_cancel/http_cancel.dart';
CancelToken cancelToken = CancelToken();
Future<SearchResults> search(String query) async {
try {
http.Response response = await http.get(Uri.parse('$baseUrl/search?q=$query'),
cancelToken: cancelToken);
return SearchResults.fromJson(response.body);
} on CancelException {
// 这里可以处理取消异常
return null;
}
}
- 节流和防抖: 在触发异步操作时,使用节流和防抖策略。比如在一个自动加载更多的列表中,使用防抖避免短时间内多次触发加载更多操作。
import 'dart:async';
Debouncer debouncer = Debouncer(milliseconds: 500);
void loadMore() {
if (debouncer.canCall()) {
// 执行加载更多逻辑
fetchMoreData();
}
}
class Debouncer {
final int milliseconds;
Timer? _timer;
Debouncer({required this.milliseconds});
bool canCall() {
if (_timer?.isActive?? false) {
_timer?.cancel();
}
_timer = Timer(Duration(milliseconds: milliseconds), () {});
return true;
}
}