序文
Dart 言語はシングルスレッド モデルであるため、マルチスレッド機能を使用して Java のようなサブスレッドを開き、サブスレッドで時間のかかる操作を実行することはできません。したがって、ネットワークリクエスト、データベース操作、ファイルの読み書きなど、時間のかかる操作を非同期で実行する必要があります。
例
まず、pubspec.yaml ファイルに依存関係を追加します。
dependencies:
http: ^0.13.5
次に、新しい dart ファイルを作成して、非同期操作の使用方法を試します。プライベート メソッド startMethod() を定義し、それを async としてマークし、これが非同期メソッドであることを示します。このメソッドでは、3 つのステートメントが出力され、getHttp()方法。
getHttp() メソッドも非同期メソッドであり、時間のかかる操作 (ネットワーク リクエスト) を実行して文字列を返します。このとき、メソッドの戻り値が Future なのに、文字列も返せるのになぜ?という疑問が生じるかもしれません。心配しないで、読み続けてください。
import 'package:http/http.dart' as http;
main(){
_startMethod();
print("C start");
}
Future _startMethod() async{
print('A start');
print(await getHttp());
print('A end');
}
Future getHttp() async{
final result = await http.get(Uri.https('jianshu.com'));
return 'result :${result.headers}';
}
main メソッドを実行すると、次のような戻り値が得られます。
A start
C start
result :{...}
A end
プログラムは順番に実行されており、1 行目の出力は問題ないのに、2 行目では C start が直接出力されるのはなぜでしょうか? これは、Dart 言語の非同期メソッドの機能です。
async メソッドでは、await より前のステートメントは通常どおり実行され、await 以降のメソッドはすべて待機されて、await 以降のコード (リクエスト http) が実行され、結果が返されるまで次のコードは続行されません。
そして、await が発生すると、メソッド (_startMethod) は、上位層の呼び出し (print C start) の実行に影響を与えることなく、ただちに Future を返します。
チップ
実際、ここでは Future の使用は省略されていますが、実際、Future の後には、この関数が将来どのような種類の結果を返すかを表すジェネリック型が続きます。
省略されていないバージョン:
import 'package:http/http.dart' as http;
main(){
_startMethod();
print("C start");
}
Future<void> _startMethod() async{
print('A start');
print(await getHttp());
print('A end');
}
Future<String> getHttp() async{
final result = await http.get(Uri.https('jianshu.com'));
return 'result :${result.headers}';
}
文法
Future の操作: async と await
および キーワードは、非同期関数を定義し
async
、await
その結果を使用するための宣言的な方法を提供します。async
と を 使用するときは、次の 2 つの基本ガイドラインに留意してくださいawait
。
- 非同期関数を定義するには、
async
関数本体の前に以下を追加します。- キーワード は関数
await
内でのみ機能しますasync
。
非同期関数を定義する場合、async を関数本体の前に置く必要があります
awaitキーワードを有効にするには、非同期関数で使用する必要があります。
高度
次に、getHttp() メソッドに 2 行の印刷を追加し、実行結果を確認します。
import 'package:http/http.dart' as http;
main(){
_startMethod();
print("C start");
}
Future _startMethod() async{
print('A start');
print(await getHttp());
print('A end');
}
Future getHttp() async{
print('B http start');
final result = await http.get(Uri.https('jianshu.com'));
print('B http end');
return 'result :${result.headers}';
}
結果は次のとおりです。
A start
B http start
C start
B http end
result :{...}
A end
初めてこの結果を見たときは、少し圧倒されるかもしれません。これは実際には再帰的なアイデアであり、ルールに段階的に従えば簡単に理解できます。
プログラムは順番に実行され、最初に print A start 、次に print(await getHttp()) が実行され、_startMethod メソッドが待機を開始します。
次に、 b http startを出力し、 http.get メソッドの実行を継続すると、getHttp が待機を開始します。http.get は実行されていないため、_startMethod には Future が返されます。同様に、 print(await getHttp()) は終了せず、_startMethod は Future を返し、main メソッドはC start を同期的に実行します。
http.get実行後、 B http終了、結果出力、A終了と続けて実行します。