jQuery.Deferred 風の非同期処理ライブラリを CoffeeScript で書いてみた
jQuery のソースコードを読むのが日課の今日このごろ、みなさんはいかがお過ごしですか?
Deferred は、連鎖した非同期処理を楽にしてくれるライブラリだ。以下のエントリを読むと概要がわかる。
爆速でわかるjQuery.Deferred超入門 - Yahoo! JAPAN Tech Blog
結局jQuery.Deferredの何が嬉しいのか分からない、という人向けの小話 - Qiita
jQuery の ready イベントはどういうふうに処理されているのか、ソースコードを追っているうちにぶち当たったのが、この Deferred ライブラリ。ソースコードをいくら読んでもよく理解できない。理解できない理由は、
- 無名関数が何重にもネストされている
- そのため変数名がどの値に束縛されているのかよくわからない
- さらに jQuery.extend を使って混乱に輪をかけている
など。たぶん非常に頭がいい人なら理解できるのだろうが、私には無理だった。
ソースに対する断片的理解と Deferred の仕様から、自分なりに Deferred 風のライブラリを書いてみた。CoffeeScript で書くと期待以上にコードが美しかったので、Github で公開してみた。
こんな感じで使う。
delay = (ms, task) -> setTimeout task, ms x = [] task1 = -> df = new Deferred() delay 100, -> x.push(1) df.reject() df.promise() oktask = -> d = new Deferred() delay 100, -> x.push(2) d.resolve() d.promise() ngtask = -> d = new Deferred() delay 100, -> x.push(-2) d.reject() d.promise() task2 = -> x.push(3) task3 = -> x.push(4) task1().then(oktask, ngtask).done(task2).fail(task3) delay 300, -> expect(x).toEqual([1, -2, 4])