ES6 Promiseの何が美しいのか
この記事は某JavaScript Advent Calendar 2013の2日目ではありませんし、ECMAScript Advent Calendar 2013のn日目でもありません(そんなものは本稿執筆時点で存在していない事を確認しています)。単に締め切りのある原稿を書いていて、疲れてしまって好き勝手に文章を書きたかったので、好き勝手に書いているだけです。
接頭辞にES6とつけるべきかDOMとつけるべきか迷うのですが、unwrappingされてるPromiseの話です. WHATWG DOM Standardからもそれが直接参照されてますし、ES6 Promiseあたりと呼んでおくのが妥当でしょうか。
何がいいのか
ECMAScriptとDOMの大合同コンセンサスが出るなどすっかりECMAScriptのためのDOM感が増しつつ有る今日この頃ですが、この幸せな点は何と言っても標準化されたことです。もちろん将来的に処理系にデフォルト搭載かつインターオペラビリティが向上するのがほぼ確定になるので、非常に幸せです。
ただ、Appleがビルドフラグを裁定するSafariという最大の不安要因はありますね。既にJavaScriptCoreにはチェックインされている模様ですが、不安の種は尽きません。万が一、次のSafariで有効にならなかったらと思うと夜も眠れません。もっとも、その場合は日本でiPhoneがバカ売れしているのが全ての元凶ですので、iPhoneが売れなくなってシェアが下がれば気にしなくていいので皆さんその日を待ちましょう。iPhoneユーザーの皆さんは申し訳有りませんが明日にもJailbreakして独自ビルドしてPromiseを有効にしたWebKitを頑張って使っていただきたい。Androidについてはいいから黙ってChromeかFirefoxかOperaを使え、OS同梱のWebViewを使っているだけでブラウザを名乗るアプリを使っている皆様は頼むから黙ってChromeかFirefoxかOperaを使うようにしてください。
話が脱線しましたが、標準化に伴うメリットというのは他にも有りまして、以前、ECMAScriptとアニメが大好きなConstellationさんが仰られていたのですが、たとえDraftであっても、一度お披露目されると、マトモな類似機構のライブラリであればDraftのAPIを参考にするので、使い方がだいたい固まり、ジャーゴンを覚える必要が無くなる道が開けるのでいいよねということです。それに、なんとなくPolyfill作りたくなるのでやっぱり幸せですね。
個人的にES6のPromiseの最大の素晴らしい点というのは、ユーザー(プログラミングをする開発者)に対して、Deferredを見せていないという点に尽きると思っています。
jQuery.Deferredの実装にあたり、どのような紆余曲折があったのかは知りませんが、jQuery.DeferredのAPIモデル最大の欠陥は、特権命令であるDeferredと、受け取った側からは不可侵な値コンテナであるPromiseの2つをユーザーに対して見せてしまった事に他ならないと考えています。もしかしたらコールバックによるクロージャがメモリリークを起こすなどの、やむにやまれぬ事情があったのかもしれませんが、それでも、この微妙な概念の違いをユーザーが普段から処理するようなモデルに載せてしまったのは失敗であったと強く思っています。通常の用途であれば、ユーザーはPromiseを取り扱うのであって、別にDeferredをオブジェクトとして変数に格納て取り回す必要は有りません。無論、特殊な迂回メソッドを用いてPromiseに対応するDeferredが取得できるモデルの存在は否定しませんが、そのような必要が有る場合は何かしら処理フローがおかしいと思いますので、まずリファクタリングをすべきだと思います。
ES6 Promiseにも仕様上はDeferredの概念が登場していますが、あくまでも仕様上の存在であってユーザーランドに対しては基本的に登場してきません。例外と呼べるのが、Promiseファクトリ・コンストラクタのコールバックの引数に対してDeferredのresolve()とreject()が登場する点ですが、これについては可能な限り隠蔽を施した上でAPIとして必要な露出であり、これを責める道理はどこにもありません。当初の春頃のdraftではresolve/rejectだけを行うPromiseResolverというオブジェクトが存在していましたが、実質的に無駄ということで単純に二つの引数として渡されるコールバック関数にしぼったのは非常に賢明な判断だと思います。
以上、書きたい事はこれだけです。 ES Promiseが一秒でも早くReal Webで使える日を楽しみにしております。