クラスメソッドにおける非同期処理
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> を返すメソッドは値を返しませんが、処理を続行する前に完了を確実にしたい場合は、依然として await する必要があります。
メソッド内で複数の非同期呼び出しを組み合わせたり、同じクラス内の他の非同期メソッドを呼び出したりすることもできます。
Future<String> getFullReport() async {
var temp = await fetchTemperature();
var humidity = await fetchHumidity();
return '$temp, Humidity: $humidity';
}このパターンは、API、データベース、または時間がかかるあらゆる操作といった外部リソースとやり取りするクラスにとって不可欠です。
チャレンジ
簡単非同期メソッドを使用して株価を管理し、ポートフォリオの価値を計算する株式ポートフォリオトラッカーを作成しましょう!リアルタイムの株価データの取得をシミュレートし、複数の非同期操作を組み合わせてレポートを生成するクラスを作成します。
コードを2つのファイルに整理します:
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インスタンスを作成します- 次の保有情報を追加します:
AAPLを10株、GOOGLを5株、MSFTを8株 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 して出力する
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ12非同期 OOP
Future と async/awaitStream の基礎Stream Controller非同期コンストラクタクラスメソッドにおける非同期処理まとめ - Data Fetcher