本エントリは書きかけです.が,公開しています.随時追記予定です.
P1370234 on Flickr

はじめに

去る 6月 7日(日),Kanasan.JS JSDeferred Code Reading へ参加してきました.

以前,1月17日(土)に Roppongi.JS でも開催されました が,後輩の結婚式に出席していたために参加できず,それ以来機会がありませんでした.(一人で読めたらまぁ苦労はしませんよね><)

そんなわけで,ぜひこの機会に,というのが参加に至る背景,とでもいいましょうかね.

それでは以下,当日の流れをざっと振り返ってみることにします.

なお,現在もソースコードに少し目を通しながら本エントリを書いているため,コードリーディングに関する記述が当時のものと現在のものと混在しているかも,ということを加えておきます.

会場まで

会場は 大阪府私学教育文化会館 というところ.今回は新幹線で京都駅まで,七条駅まで徒歩,京阪本線で最寄り(のひとつ)である京橋駅まで,という感じで向かいました.

京橋駅到着直前にマクドナルドが見えたので,そこで昼食...のつもりが,改札を出たとたん 京阪モール に入ってしまい,しばらく出られずにウロウロしていましたorz

結局,マクドナルドに寄るには時間が足りなくなってきたので,直接会場に向かいました.

会場

P1370227 on Flickr P1370232 on Flickr

ドキュメントチェックと簡単なコーディング

まずは 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;
  • valueDeferred オブジェクトの場合,自身の _next プロパティを value_next プロパティとする.???
  • valueDeferred オブジェクトでない場合,_nextプロパティが指すDeferredオブジェクトの_fireメソッドを,nextvalue を引数に呼び出す.
  • 最後に,自身を返す.

まとめると,callbackプロパティに登録されている,登録されていなければデフォルトの,関数を自身のメソッドとして呼び出し,その結果を次の Deferred オブジェクトに伝えて,その callbackプロパティに登録さr(ry ...といった,処理実行の連鎖を引き起こす,といった感じになるのかなぁ...

Deferred.parallel

  • 第1引数 dlDeferredオブジェクトの配列,もしくは,同オブジェクトを値に持つハッシュ(オブジェクト).

[あとで読み直す]
[あとで書く]

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

P1370237 on Flickr

flickr の写真をブログとかで掲載するためのHTMLを簡単にコピペするためのgreasemonkey

P1370240 on Flickr

生comet

P1370242 on Flickr

stack stock books api + jquery

私は半年以上放置で恐縮ながら,DQWindowManager について少々.

懇親会・帰り道

P1370248 on Flickr
  • XULって「ずーる」って読むんだ.
  • 言語の教養的な意味で,smalltalkについて勉強してみるといいよ.
  • carbon emacs を複数起動するには

    open -n /Applications/Emacs.app

    とかするといいよ.

などなど.

帰りは,行きの真逆を辿ってきました.途中,京都タワーが光っていたので撮ってみました.三脚がなかったのでブレてますかね...

P1370260 on Flickr

おわりに

以上,Kanasan.JS JSDeferred Code Reading の参加報告でした.

今回の進捗としては,全体の半分くらい,でしょうか.

JSDeferred は行数こそそんなに多くはないものの,メソッド 1つ 1つの内容がかなり濃ゆいです.JavaScript のエッセンスが詰まっています...といろいろなところでさんざん言われていますが,それを身をもって知ることができました.(現在進行形ですが><)

個人的には,読み進める中で前の方で定義されたメソッドが目に入るたびに,定義部分へ戻って挙動を再確認する,ということを何度も何度も繰り返してしまい,なかなか進められませんでした.

コード中で呼び出される頻度の高いメソッド・関数を把握して,それらから順に理解していくと効率がいいのかな..

今回学んだことは,JSDeferred のような濃ゆいライブラリを書かないまでも,普段から書くちょっとした JavaScript コードにも十分に反映でき得るものだったと思います.(自分が過去に書いたコードをリファクタリングするとどうなるんでしょうねw)

...あーっと,DeLLa.JS も再開しないとですね.7月にはなんとか...

参考

こちらもあわせてどうぞ

Leave a Reply

直近のつぶやきを読み込みちゅう...