投稿

5月, 2013の投稿を表示しています

[Dart]Stream.listenに2重のリスナ

DartのStreamのリスナ管理の話 Stream.listenを使ってリスナを貼るのだが、やればやるほどリスナが貼られていくよね。 new ButtonElement() ..onClick.listen( ()=> print("hoge") ) ..onClick.listen( ()=> print("hoge") ); 結果 >hoge >hoge これは、onClick呼び出し内でStream<T>がnewされるためだ。(EventStreamProvider.forTargetを内部で呼んでいる) そして、listen()でさらにStreamSubscription<T>がnewされている。 実際にリスナを持つのは、このStreamSubscriptionで、こいつはリスナを一つしか持てない。 ということは、リスナは追加ではなく差し替えにしたい場合、こいつのonDataを書き換えてやれば良いわけだ。 ちなみに、StreamSubscription.cancel()を呼び出すことで、それ以降のイベントの配信を停止できる。 下のソースは、クリックされるたびにTextを変更し、2回目のクリックでそれ以降のイベントの受信を停止するサンプルだ。 ButtonElement btn = new ButtonElement(); StreamSubscription<Event>  s = btn. onClick .listen( null ); s.onData( ( e ) {   btn. text = "first click" ;   s.onData( ( e ) { btn. text = "second click" ;s.cancel(); } ); } ); 参考: Getting Your Feet Wet with Streams

[Dart]Streamを返す関数

例えばElementのonClickなど、Streamを返す関数はDartの標準ライブラリに多数存在する。 というわけで、自分もStreamを返す関数を作りたい。 以下、サンプル。 StreamController<String> cont = new StreamController(); Stream<String> get onReceive => cont.stream; void update() { HttpRequest.request("http://...../data") .then( (HttpRequest req) { cont.add(req.responseText); if( isFinish ) // 終了フラグ cont.close(); }) .catchError( (e) { cont.addError(e); }); } キモはStreamControllerだ。 addメソッドでデータを送り、終了したらcloseメソッドでストリームを閉じる。 エラーはaddErrorメソッドで通知。 ちなみに、このサンプルでデータ取得ハンドラを貼るには下記のようにする。 a.onReceive.listen( (String data) => print(data) ); ※上記サンプルがクラスとして定義されて変数aになっているとする。

[Dart]Futureを返す関数

Dartで標準で用意されているメソッドはFutureを返すものがある。 これは遅延を伴う処理を、無駄なく行うための重要な機構だ。 というわけで自分のメソッドもFutureを返すようにしたいのだが、 そのやり方は下記の通り。 Future<chartdata> httpAccessTest() { Completer comp = new Completer(); HttpRequest.request("http://..../xxx") .then( (HttpRequest req) { // 成功した時 comp.complete(req.responseText); }) .catchError( (e) => comp.completeError(e) ); // 失敗した時 return comp.future; } これはhttpでデータを取得するサンプルだ。 Completerオブジェクトを使用するのがミソ。 っていうか、それしかないが。 正常終了の結果はcompleteメソッドで通知。 エラーは、completeErrorメソッドを使用して通知。サンプルでは元の処理でThrowされているものをそのまま転送している。 ちなみに、Completerが使えるのは一回こっきりだ。使い回しはできない。 Futureの使い方 http://www.dartlang.org/articles/using-future-based-apis/ Futureのエラーハンドリング方法 http://www.dartlang.org/articles/futures-and-error-handling/