Dart Streamクラスlisten()メソッド

Dar言語StreamクラスtoSet()メソッドDart

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

コメント

タイトルとURLをコピーしました