はじめに
去る 6月 7日(日),Kanasan.JS JSDeferred Code Reading へ参加してきました.
以前,1月17日(土)に Roppongi.JS でも開催されました が,後輩の結婚式に出席していたために参加できず,それ以来機会がありませんでした.(一人で読めたらまぁ苦労はしませんよね><)
そんなわけで,ぜひこの機会に,というのが参加に至る背景,とでもいいましょうかね.
それでは以下,当日の流れをざっと振り返ってみることにします.
なお,現在もソースコードに少し目を通しながら本エントリを書いているため,コードリーディングに関する記述が当時のものと現在のものと混在しているかも,ということを加えておきます.
会場まで
会場は 大阪府私学教育文化会館 というところ.今回は新幹線で京都駅まで,七条駅まで徒歩,京阪本線で最寄り(のひとつ)である京橋駅まで,という感じで向かいました.
京橋駅到着直前にマクドナルドが見えたので,そこで昼食...のつもりが,改札を出たとたん 京阪モール に入ってしまい,しばらく出られずにウロウロしていましたorz
結局,マクドナルドに寄るには時間が足りなくなってきたので,直接会場に向かいました.
会場
ドキュメントチェックと簡単なコーディング
まずは JSDeferred がどんなものか,というのを確認すべく,ドキュメントを読みながら実際に動かしてみることから始まりました.
一行書いて確認してもう一行つなげて...を繰り返したのが次のコードです.物覚えが遅いので,3つのメソッドくらいしか使えていませんが><
Deferred.define(); next( function() { alert( 'hoge' ); }) .wait(1) .next( function() { alert( 'fuga' ); }) ; parallel([ next( function() { alert('hoge'); }) .wait(1) .next( function() { alert('hogehoge'); }) , next( function() { alert('fuga'); }) ]) .next( function() { alert( 'piyo' ); }) .next( function() { loop( 5, function( n ) { alert(n); }) .loop( {begin:1, end:10, step:3}, function(n, o) { alert( [n, o.step] ); }); }) ;
コードリーディング
これを書いている現在ソースコードに再度目を通しもしているので,当日の記録というよりは,実装のメモというか覚え書きというか...そんなものになりそうです.
ちなみに,対象のバージョンは 0.2.2 です.
コンストラクタ
83 | function Deferred() = { return (this instanceof Deferred) ? this.init() : new Deferred() } |
Deferred() としても new Deferred() としても同じものが返る,というか,どちらの形にしろ最後は this.init() が呼ばれる,ということですね.
私にとっては,しょっぱなの1行から勉強になります.
Deferred.ok
引数をそのまま返す.
Deferred.ng
引数とともに例外を投げる.
メソッド
86 | Deferred.prototype = { |
この書き方で始めると,constructor プロパティがなくなるよね,というお話が出てましたね.
init
_nextプロパティcallbackプロパティ
next
※ 先に _post メソッドを把握した方がよさげ
- 第1引数
fun:関数. callbackプロパティのokプロパティに,第1引数の関数が割り当てられたDeferredオブジェクトを返す.- つまり,
callbackプロパティが指すオブジェクトのokメソッドが第1引数の関数であるようなDeferredオブジェクトを返す,ということ?
error
※ 先に _post メソッドを把握した方がよさげ.
- 第1引数
fun:関数 nextメソッドの記述をs/ok/ng/g;した感じ.
call
※ 先に _fire メソッドを把握した方がよさげ.
- 第1引数
val:値?何の? 'ok',valを引数に,_fireメソッドを呼び出す.
fail
※ 先に _fire メソッドを把握した方がよさげ.
- 第1引数
err:エラーオブジェクト? 'ng',errを引数に,_fireメソッドを呼び出す.
cancel
102 | (this.canceller || function () {})(); |
cancellerメソッドが定義されていればそれを実行,そうでなければなにもしない,- そうか,こういう書き方もできるのね.
102 | return this.init(); |
- そして初期化して自身を返す,でいいのかな?
- つまり,
_nextプロパティにDeferredオブジェクトが登録されていて実行予定だった処理を「キャンセルする」ということかな?
_post
- 第1引数:’ok’ or ‘ng’.
- 第2引数:関数
_nextプロパティに新しいDeferredオブジェクトを生成._nextプロパティの_callbackプロパティのokまたはngプロパティに,第2引数で指定した関数を割り当てる._nextプロパティが指すDeferredオブジェクトを返す.
_fire
- 第1引数
okng:’ok’ or ‘ng’. - 第2引数
value:何の値?
113 114 115 116 117 118 119 | next = "ok"; try { value = this.callback[okng].call(this, value); } catch (e) { next = "ng"; value = e; } |
callbackプロパティが指すオブジェクトのokもしくはngメソッドを,自身のメソッドとして呼ぶ.この際,第2引数で与えられたものをメソッドの引数としている.このメソッドの返り値でvalueを置き換える.- 第1引数が
ngのとき,例外が発生する場合がある. - 例外が発生した場合,
valueにはエラーオブジェクトが入る.
120 121 122 123 124 125 | if (value instanceof Deferred) { value._next = this._next; } else { if (this._next) this._next._fire(next, value); } retturn this; |
valueがDeferredオブジェクトの場合,自身の_nextプロパティをvalueの_nextプロパティとする.???valueがDeferredオブジェクトでない場合,_nextプロパティが指すDeferredオブジェクトの_fireメソッドを,next,valueを引数に呼び出す.- 最後に,自身を返す.
まとめると,callbackプロパティに登録されている,登録されていなければデフォルトの,関数を自身のメソッドとして呼び出し,その結果を次の Deferred オブジェクトに伝えて,その callbackプロパティに登録さr(ry ...といった,処理実行の連鎖を引き起こす,といった感じになるのかなぁ...
Deferred.parallel
- 第1引数
dl:Deferredオブジェクトの配列,もしくは,同オブジェクトを値に持つハッシュ(オブジェクト).
[あとで読み直す]
[あとで書く]
Deferred.wait
[あとで読み直す]
[あとで書く]
Deferred.next
私が少々読み遅れていたため,ここまでたどり着けなかったです orz
[2009/06/07 15:11:44] 37to: nextについては、205行目のnext_defaultだけ見ておくとよいそうです
[2009/06/07 15:12:19] 37to: その他のnext系関数は、高速化の為の関数との事です
チャットログ JSDefferred コードリーディング ( Kanasan.JS : JavaScript Workshop in Kansai)
Deferred.next_default
[あとで読み直す]
[あとで書く]
Deferred.next_faster_way_readystatechange
※ Kanasan.JS では未読.
[あとで読む]
[あとで書く]
Deferred.next_faster_way_Image
※ Kanasan.JS では未読.
[あとで読む]
[あとで書く]
Deferred.call
[あとで書く]
Deferred.loop
※ Kanasan.JS では未読.
[あとで読む]
[あとで書く]
Deferred.register
[あとで書く]
すごく混乱.
[あとで書く]
388行 - 389行
388 389 | Deferred.register("loop", Deferred.loop); Deferred.register("wait", Deferred.wait); |
[あとで書く]
Deferred.define
※ Kanasan.JS では未読.
[あとで読む]
[あとで書く]
ゆるふわTechTalk
flickr の写真をブログとかで掲載するためのHTMLを簡単にコピペするためのgreasemonkey
生comet
stack stock books api + jquery
私は半年以上放置で恐縮ながら,DQWindowManager について少々.
懇親会・帰り道
- XULって「ずーる」って読むんだ.
- 言語の教養的な意味で,smalltalkについて勉強してみるといいよ.
-
carbon emacs を複数起動するには
open -n /Applications/Emacs.app
とかするといいよ.
などなど.
帰りは,行きの真逆を辿ってきました.途中,京都タワーが光っていたので撮ってみました.三脚がなかったのでブレてますかね...
おわりに
以上,Kanasan.JS JSDeferred Code Reading の参加報告でした.
今回の進捗としては,全体の半分くらい,でしょうか.
JSDeferred は行数こそそんなに多くはないものの,メソッド 1つ 1つの内容がかなり濃ゆいです.JavaScript のエッセンスが詰まっています...といろいろなところでさんざん言われていますが,それを身をもって知ることができました.(現在進行形ですが><)
個人的には,読み進める中で前の方で定義されたメソッドが目に入るたびに,定義部分へ戻って挙動を再確認する,ということを何度も何度も繰り返してしまい,なかなか進められませんでした.
コード中で呼び出される頻度の高いメソッド・関数を把握して,それらから順に理解していくと効率がいいのかな..
今回学んだことは,JSDeferred のような濃ゆいライブラリを書かないまでも,普段から書くちょっとした JavaScript コードにも十分に反映でき得るものだったと思います.(自分が過去に書いたコードをリファクタリングするとどうなるんでしょうねw)
...あーっと,DeLLa.JS も再開しないとですね.7月にはなんとか...











