しびら

技術ネタのメモとか。

promiseでjavascriptの非同期による死のピラミッドをなんとかする

   

1a5aab66-8eaf-1684-01f1-923f07c3f971

JavaScriptで非同期のメソッドをつなげる場合、コールバック関数を記述するのにネストするため、コードがだんだん右下へと流れていき、メソッドをつなげる数が多くなるほど大きなピラミッドが形成されます。(英語ではこのことをPyramid of doom(死のピラミッド)と表現しています)

Promiseを使ってピラミッドを回避する

Promise インターフェースは作成時点では分からなくてもよい値へのプロキシです。プロミスを用いることで、非同期アクションの成功や失敗に対するハンドラを関連付けることができます。これにより、非同期メソッドは、最終的な値を返すのではなく、未来のある時点で値を持つプロミスを返すことで、同期メソッドと同じように値を返すことができるようになります。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise

 

特定のブラウザでは対応していない場合があるため、クライアント側で使用する場合は注意する必要があります。詳細は下記リンク参照。

http://caniuse.com/#feat=promises

こちらを確認すると、IEはEdge以外は対応していないので、クライアント側での利用はまだ控えたほうが良さそうです。

Promiseの実行サンプル

こちらの実行結果は以下となります。Promiseで42という値を返す処理を非同期で実行し、完了した時点でthenの処理が走ることでconsoleに出力されました。

これだけではちょっとわかりにくいので続いて以下のコードを書きました。

こちらのコードの出力をconsole.logにしただけですが。

testPromise()を実行した結果は以下のようになります。プロミスの成功はsetTimeoutで指定された秒数待機した後に呼ばれるので最後の行の出力だけ遅れます。

ここで気になるのはtestPromiseを連続して2回実行した場合のの結果です。

結果は以下。最後のsetTimeoutにより出力が遅れるため、先に次のtestPromiseの処理結果が出力されていることが分かりますね。

 

これでピラミッドは回避できそうです。次は実践的なコードに使ってみたいところですが、IE対応できるライブラリを探してみるところらでしょうか。Angularにはそれっぽいのがあったような。

参考

JavaScript Promiseの本
http://azu.github.io/promises-book/

今更だけどPromise入門
http://qiita.com/koki_cheese/items/c559da338a3d307c9d88

MDN Promise
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise

 

 

 

 

 - Javascript , ,