클래스 메서드에서의 비동기 처리
Coddy Dart 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 110개 중 80번째.
팩토리 메서드를 사용하여 비동기 초기화를 처리하는 방법을 알게 되었으니, 이제 일반 인스턴스 메서드를 비동기로 만드는 방법을 살펴보겠습니다. 이는 간단합니다. 어떤 메서드에든 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>를 반환하는 메서드는 값을 반환하지 않지만, 계속 진행하기 전에 해당 메서드가 완료되었는지 확인하려면 여전히 await가 필요합니다.
메서드 내에서 여러 비동기 호출을 결합하거나 동일한 클래스의 다른 비동기 메서드를 호출할 수도 있습니다:
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를 await하고, 보유 수량을 곱하여 총 가치를 반환해야 합니다. 심볼이 보유 현황에 없으면 0.0을 반환합니다.Future<double>를 반환하는 비동기 메서드getTotalValue(). 이 메서드는 각 주식에 대해getStockValue를 await하고 결과를 합산하여 모든 보유 자산의 결합된 가치를 계산해야 합니다.Future<String>를 반환하는 비동기 메서드generateReport(). 이 메서드는 각 주식의 가치와 총액을 보여주는 보고서를 작성해야 합니다. 각 줄을[symbol]: $[value](소수점 1자리 가치) 형식으로 구성하고, 마지막 줄에Total: $[totalValue](마찬가지로 소수점 1자리)를 추가합니다.
- 주식 심볼과 소유한 주식 수를 저장하는
main.dart: 포트폴리오 파일을 임포트하고 클래스 내에서 비동기 메서드가 어떻게 함께 작동하는지 보여줍니다:StockPortfolio인스턴스를 생성합니다.- 다음 보유 자산을 추가합니다: 10주의
AAPL, 5주의GOOGL, 8주의MSFT Fetching portfolio data...를 출력합니다.generateReport()의 결과를 await하고 출력합니다.
generateReport()가 동일한 클래스 내의 다른 비동기 메서드를 호출하는 방식과 각 메서드가 다른 메서드를 기반으로 구축되는 방식에 주목하세요. 소수점 값을 형식화하려면 toStringAsFixed(1)를 사용하세요!
예상 출력:
Fetching portfolio data...
AAPL: $1020.0
GOOGL: $637.5
MSFT: $816.0
Total: $2473.5치트 시트
인스턴스 메서드를 비동기로 만들려면, 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');
}
}비동기 메서드는 인스턴스 변수에 접근하고 수정할 수 있습니다. 호출자는 결과를 await해야 합니다. Future<void>를 반환하는 메서드는 값을 반환하지 않지만, 완료를 보장하기 위해 여전히 await가 필요합니다.
비동기 메서드는 같은 클래스 내의 다른 비동기 메서드를 호출할 수 있습니다:
Future<String> getFullReport() async {
var temp = await fetchTemperature();
var humidity = await fetchHumidity();
return '$temp, Humidity: $humidity';
}이 패턴은 API나 데이터베이스와 같은 외부 리소스와 상호작용하는 클래스에 필수적입니다.
직접 해보기
import 'portfolio.dart';
void main() async {
// TODO: StockPortfolio 인스턴스 생성
// TODO: 보유 주식 추가:
// - AAPL 10주
// - GOOGL 5주
// - MSFT 8주
// TODO: "Fetching portfolio data..." 출력
// TODO: generateReport()의 결과를 await하고 출력
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.