Dart Streamクラスのlisten()メソッドについてメモ書き。
listen()はStreamのサブスクリプションを追加するメソッド。
listen()の戻り値はStreamSubscription<T>型。StreamSubscriptionは受信したStreamをコントロールするためのクラス。
listen()にはonData、onError、onDoneハンドラーが用意されており、各ハンドラーのコールバック関数としてonData()、onError:()、onDone:()が用意されている。
- onData:Streamからデータを受信した時に実行されるハンドラー
- onError:Streamからエラーを受信した時に実行されるハンドラー
- onDone:Streamから完了通知を受信した時に実行されるハンドラー
必須はonData()。onError:()とonDone:()は名前付きオプション引数で省略可能である。名前付きオプション引数としてbool型のcancelOnError:も用意されている。cancelOnError:をtrueに設定するとエラーを受信したタイミングでサブスクリプションがキャンセルされる。デフォルトはfalse。
StreamSubscriptionクラスにも同様のメソッドが用意されており、listen()呼出後に使用することができる。StreamSubscriptionクラスには他にもメソッドやプロパティが用意されており、一時停止等より高度な制御ができる。listen()についての記事なので、StreamSubscriptionクラスの詳細は記載しない。
onData()、onError:()、onDone:()の戻り値はvoid型。
onData()は受信したStreamイベントを引数として受け取り、イベントに対する実行処理を記述する。
onError:()は引数として「エラーオブジェクト」、もしくは「エラーオブジェクト、スタックトレース」を受け取り、例外発生時の処理を記述する。
onDone:()は引数を受け取らず、Streamから完了通知を受信したタイミングで実行される。
それではコーディングで動作確認。
i=3の時に例外を発生させる。cancelOnError:は明示的にfalseにする。
void main() {
final stream = () async* {
for (int i = 0; i < 5; i++) {
if (i == 3) {
throw "Error Test";
}
yield i;
}
}();
stream.listen(
(event) {
print(event);
},
onError: (e, st) {
print("Error:$e");
print("StackTrace:$st");
},
onDone: () => print("onDone"),
cancelOnError: false,
);
}
実行結果。
cancelOnError:がfalseなのでonDone:()まで実行される。
0
1
2
Error:Error Test
StackTrace:#0 main.<anonymous closure> (file:///Users/**********/app/dart/dev2/bin/dev2.dart:5:9)
<asynchronous suspension>
#1 main.<anonymous closure> (file:///Users/**********/app/dart/dev2/bin/dev2.dart:11:5)
<asynchronous suspension>
onDone
次はcancelOnError:をtrueに設定。
void main() {
final stream = () async* {
for (int i = 0; i < 5; i++) {
if (i == 3) {
throw "Error Test";
}
yield i;
}
}();
stream.listen(
(event) {
print(event);
},
onError: (e, st) {
print("Error:$e");
print("StackTrace:$st");
},
onDone: () => print("onDone"),
cancelOnError: true,
);
}
実行結果。
trueの場合は後続の処理がキャンセルされるので、onDone:()は実行されない。
0
1
2
Error:Error Test
StackTrace:#0 main.<anonymous closure> (file:///Users/**********/app/dart/dev2/bin/dev2.dart:5:9)
<asynchronous suspension>
#1 main.<anonymous closure> (file:///Users/**********/app/dart/dev2/bin/dev2.dart:11:5)
<asynchronous suspension>
次はonError:()をコメントアウトしてエラーを発生させる。
cancelOnError:はtrue。
void main() {
final stream = () async* {
for (int i = 0; i < 5; i++) {
if (i == 3) {
throw "Error Test";
}
yield i;
}
}();
stream.listen(
(event) {
print(event);
},
// onError: (e, st) {
// print("Error:$e");
// print("StackTrace:$st");
// },
onDone: () => print("onDone"),
cancelOnError: true,
);
}
実行結果。
「Unhandled exception」が発生する。
cancelOnError:がtrueなのでonDone:()は実行されない。
0
1
2
Unhandled exception:
Error Test
#0 main.<anonymous closure> (file:///Users/**********/app/dart/dev2/bin/dev2.dart:5:9)
dev2.dart:5
<asynchronous suspension>
#1 main.<anonymous closure> (file:///Users/**********/app/dart/dev2/bin/dev2.dart:11:5)
dev2.dart:11
<asynchronous suspension>
次はcancelOnError:をfalseにする。
void main() {
final stream = () async* {
for (int i = 0; i < 5; i++) {
if (i == 3) {
throw "Error Test";
}
yield i;
}
}();
stream.listen(
(event) {
print(event);
},
// onError: (e, st) {
// print("Error:$e");
// print("StackTrace:$st");
// },
onDone: () => print("onDone"),
cancelOnError: false,
);
}
実行結果。
cancelOnError:がfalseなので、Unhandled exceptionが発生してもonDone:()まで実行される。
0
1
2
onDone
Unhandled exception:
Error Test
#0 main.<anonymous closure> (file:///Users/**********/app/dart/dev2/bin/dev2.dart:5:9)
dev2.dart:5
<asynchronous suspension>
#1 main.<anonymous closure> (file:///Users/**********/app/dart/dev2/bin/dev2.dart:11:5)
dev2.dart:11
<asynchronous suspension>
listen()はonDate()以外名前付きオプション引数なので、他は省略できる。
void main() {
final stream = () async* {
for (int i = 0; i < 5; i++) {
yield i;
}
}();
stream.listen(
(event) {
print(event);
},
);
}
実行結果。
0
1
2
3
4
コメント