BIOGRAPHYREADME2016.04.16これからのJSの非同期処理関数は全てPromiseを返させるべきこのブログははてなブログからの移行記事です。はじめにJSで非同期関数を書く時、個人的に意識してる話です。別にTipsとかじゃないです。́・ω・`)非同期関数を使いこなすJSを書いたことがある人なら知ってるであろう非同期処理ですが、僕は非同期処理はなるべくPromiseオブジェクトを返す関数に切り分けていくべきだと思っています。極端な例として「APIその1を叩いて、その結果からAPIその2を叩いて、その結果からAPIその3を叩いて、それを画面に描画するぞい!」というコードを書いてみます。悪い例:関数で処理をラップしないAPIが綺麗に整っていれば最高ですが、現実は得てしてあまくありません。3種類のAPIを叩くわけですがそれらのレスポンススキーマは全て違うとしましょう。いわゆるネスト地獄ですね。res.count.....)『上司「APIその2のレスポンススキーマ変わるから対応してよ」』って時にその処理部分を探すのが大変(grepかけますか???)悪い例:コールバック関数を引数に取る関数を書く先ほどあがっていた悪い点のうち、2点目を解決してみましょう。処理を関数でわけてみます。}});コード量が増えたものの、先程よりは多少よくなったのではないでしょうか。最初の例と比べると以下の点が改善されたかと思います。それぞれのAPIへのアクセスを関数化したので使い回しがきく/修正が容易レスポンススキーマについては関数の中で完結してるので実際に関数を使う時に意識しなくてよいしかし、以下の問題については未だ未解決です。ネストが深くて可読性が低いまた、このアプローチだと以下のような関数が混ざった時に混乱します。ついでresとなっていました。ここで定義されている関数ではその順番が逆になっています。{});というように使いたい時、第二引数の関数に最終的に何が渡されるかを実装者は知る必要があります。丁寧にJSDoc等でコメントが書かれていればそれで済みますが、世のコードの9割はそんなに親切ではなく結局実装を追う羽目になることが多いと思います。});さぁ!前回の例での問題が解決されました。前回の問題として以下のものがありました。ネストが深いコールバック関数に渡される引数の順番を知る必要があるコード量は増えましたが、Promiseを返す関数はthen()とcatch()を使ってつなげることができます。最新のJSではAPIでもこのthenableの考え方が浸透しており、これを使って非同期処理の順番をネストの深さを変えずにつなげることが可能になります。コールバック関数に渡される引数の順番についても知る必要はなくなりました。Promiseを返す関数ではresolve()とreject()の2種類に縛られます。前者は成功時の返り値、後者はエラー時の返り値となります。それらをthen()、catch()で捉えて、行いたい処理を書きます。reject()で縛られるのがいいかなと思います。今まではコールバック関数に何が返ってくるのかドキュメントを読む必要がありましたが、Promise化されていれば成功か失敗かで考えるだけで済みます。あるAPIを叩く関数をPromise化しておけば内部実装がどうなっていようと使う側はthen()で結果を受け取り、catch()でエラーハンドリングを行えばよいのです。ある程度冗長には見えますがこれからはPromiseが常識になっていきますし非同期関数は全部Promiseでいいんじゃないかなと思ってます。実際に使いたいけど動かないんでしょう?いいえ!動きます。IE8まではpolyfillライブラリであるes6-promiseを使用することで問題なく使うことができます。知りたいPromiseの本がおすすめです。async-awaitで書きたいので非同期な関数はPromiseで提供されてると助かりますね。