类方法中的异步编程
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 80 课,共 110 课。
现在你已经了解了如何使用工厂方法处理异步初始化,接下来看看如何让常规实例方法变为异步方法。这很简单,只需在任意方法前添加 async,并让它返回一个 Future。
class WeatherService {
String _location;
WeatherService(this._location);
Future<String> fetchTemperature() async {
await Future.delayed(Duration(seconds: 1));
return '22°C in $_location';
}
Future<void> updateLocation(String newLocation) async {
await Future.delayed(Duration(milliseconds: 500));
_location = newLocation;
print('Location updated to $_location');
}
}
Future<void> main() async {
var service = WeatherService('London');
var temp = await service.fetchTemperature();
print(temp);
await service.updateLocation('Paris');
}异步方法可以像普通方法一样访问和修改实例变量。关键区别在于,调用方必须对结果使用 await。返回 Future<void> 的方法不会返回值,但如果你想确保它们完成后再继续,就仍然需要等待它们。
你还可以在一个方法中组合多个异步调用,或者在同一个类中调用其他异步方法:
Future<String> getFullReport() async {
var temp = await fetchTemperature();
var humidity = await fetchHumidity();
return '$temp, Humidity: $humidity';
}这种模式对于与外部资源交互的类至关重要,例如 API、数据库,或任何需要耗费时间的操作。
挑战
简单让我们构建一个股票投资组合跟踪器,使用异步方法管理股票价格并计算投资组合价值!你将创建一个类,模拟获取实时股票数据,并组合多个异步操作来生成报告。
你将把代码分成两个文件:
portfolio.dart:创建一个用于跟踪股票及其数量的StockPortfolio类。这个类应包含:- 一个名为
_holdings的私有Map<String, int>,用于存储股票代码和持有的股份数量 - 一个将
_holdings初始化为空映射的构造函数 - 一个用于添加或更新股票持仓的方法
addStock(String symbol, int quantity)(非异步) - 一个返回
Future<double>的异步方法fetchPrice(String symbol)。模拟延迟 50 毫秒,然后返回按以下方式计算的价格:股票代码的长度乘以 25.5 - 一个返回
Future<double>的异步方法getStockValue(String symbol)。此方法应等待该股票代码对应的fetchPrice,将价格乘以持有数量,并返回总价值。如果持仓中没有该股票代码,则返回 0.0 - 一个返回
Future<double>的异步方法getTotalValue()。此方法应通过等待每只股票对应的getStockValue并对结果求和,计算所有持仓的总价值 - 一个返回
Future<String>的异步方法generateReport()。此方法应生成一份报告,显示每只股票的价值和总价值。每行的格式为[symbol]: $[value](value 保留 1 位小数),最后一行为Total: $[totalValue](同样保留 1 位小数)
- 一个名为
main.dart:导入你的投资组合文件,并演示异步方法如何在类中协同工作:- 创建一个
StockPortfolio实例 - 添加以下持仓:
AAPL10 股,GOOGL5 股,MSFT8 股 - 打印
Fetching portfolio data... - 等待并打印
generateReport()的结果
- 创建一个
注意,generateReport() 会在同一个类中调用其他异步方法,而且每个方法都基于其他方法的结果继续完成工作。使用 toStringAsFixed(1) 格式化小数值!
预期输出:
Fetching portfolio data...
AAPL: $1020.0
GOOGL: $637.5
MSFT: $816.0
Total: $2473.5亲手试试
import 'portfolio.dart';
void main() async {
// TODO: 创建一个 StockPortfolio 实例
// TODO: 添加持仓:
// - AAPL,10 股
// - GOOGL,5 股
// - MSFT,8 股
// TODO: 打印 "Fetching portfolio data..."
// TODO: 等待并打印 generateReport() 的结果
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器