2013 Future & Stream in Dart
Future & Streamin Darttomochikahara@zetta1985
View Slide
Agenda● Future API● Stream API
Future APIfor Ansynchronous Programming
What is a Future?● 「先物」○ 別名Promise。○ 処理結果を必要となる時点まで保持する○ 並列処理のデザインパターン■ Dartでは非同期なだけで並列処理は必須でない● Futureの値を決めるCompleter○ Futureはあくまでも値を保持するのみ○ 計算結果をFutureに与えるのがCompleter● dart:io, indexed_dbなどで利用
Future & CompleterCompleterFutureFutureCaller CalleeFuture echoToMountain(String yo_ho);call echoToMountaincreategetFuturereturn Futurethen((reply) => catchMyEar(reply))complete(reply)Execution
Future & Completerimport "dart:async";Future echoToMountain(String yo_ho) {var completer = new Completer();new Timer(new Duration(milliseconds: 5000), () {completer.complete(yo_ho);});return completer.future;}void main() {print("before echoToMountain");var future = echoToMountain("YooooHooooo");future.then(print);print("after echoToMountain");}
Future Examplenew File("./foo.txt").fullPath().then((fullpath) {print("foo.txt's fullpath is $fullpath");}).catchError((e) {print("foo.txt is not exists.");});File IO(Async try-catch)HTTPRequest(Async Process Chain)var uri = Uri.parse("http://tomochikahara.com");new HttpClient().getUrl(uri).then((HttpClientRequest req){// prepare requestreq.headers.add("contentType", "text/html");return req.close();}).then((HttpClientResponse res) {res.transform(new StringDecoder()).forEach(print);});
Stream APIfor sequence of any data
What is a Stream?● イベントの「流れ」○ 単なる遅延リスト。○ 何回も使えるFuture。○ 値が発すること=イベント、と表現○ Producer - Consumer Pattern■ Dartでは非同期なだけで並列処理は必須でない● DOM EventやByte IO、標準入力などで利用
StreamWhat is a Stream?Controller(Sink)SubscriptionD C B' A' ・・・TransformerF Eaddlisten
Streamvar controller = new StreamController();controller.add("A");var stream = controller.stream;stream.listen((str) => print(str),onError : (e) => print("Error"),onDone : () => print("Done"));controller.add("B");controller.add("C");controller.addError(new StateError("Illegal State"));controller.add("D");controller.close();
Stream Subscriptionvar controller = new StreamController();controller.add("A");var stream = controller.stream;var subscription = stream.listen((str) => print(str),onDone : () => print("Done"));subscription.onError((e) {subscription.cancel();});controller.add("B");controller.add("C");controller.addError(new StateError("Illegal State"));controller.add("D");controller.close();
Stream Transformervar controller = new StreamController();var stream = controller.stream;var transformer = new StreamTransformer(handleData : (int value, EventSink sink) {sink.add("$value:(1)");sink.add("$value:(2)");},handleDone : (EventSink sink) {sink.add("Done!");});stream.transform(transformer).forEach(print);for (var i = 0; i < 10; i++) {controller.add(i);}controller.close();
Stream Examplequery("input#hello").onClick.listen((MouseEvent e) {window.alert("hello, world.");});DOM EventFile Access StreamSubscription> subscription;subscription = new File('bar.txt').openRead().listen((bytes) {for (var b in bytes) {print(new String.fromCharCode(b));if (b == '#'.codeUnitAt(0)) {subscription.cancel();return;}}});
Stream Example標準入力HTTP Server HttpServer.bind("127.0.0.1", 8080).then((HttpServer server) {server.listen((HttpRequest req) {req.response.write("This message from my server.");req.response.close();});});print("Please Input A.");var stream = stdin.transform(new StringDecoder()).transform(new LineTransformer());stream.listen((str){print("Your input's length : ${str.length}");print(str == "A" ? "Just A." : "Not A.");});