ES7ではPromise処理を簡素化できるawait/asyncが追加されています。これによってコールバック地獄からPromiseによって抜け出せたとの同様に、Promiseによる then/catch 地獄から抜け出せるようになります。
サンプルコード
例えば処理を2秒間遅らせて、その結果を取得すると言った処理を考えてみます。ES5で書くと次のようになるでしょう。
さらにdelayを2回呼び出すと次のようになります。ネストが一つ深くなります。
Promiseの場合
Promiseを使った場合は次のようになります。ネストが深くならず、thenを使ったメソッドチェーンが可能になります。
awaitを使った場合
さらにawaitを使った場合です。ネストが一段減りますが、処理を行う関数を async で囲む必要があるので、最低一つの関数の中で処理する必要があります。Promiseだけの場合は必ずしもmain関数は必要ではありません。
awaitのコードをES5に変換する
ではこのawaitのコードをBabelを使ってES2015のコードに変換した場合、どのようなコードになるのでしょうか。以下のコードはそのままnodeで動くわけではありませんが、次のようなコードが生成されます。
await的な機能を実現するために while ループを続けているのが分かります。ちなみにこれは delay を一回しか使っていない場合です。
delay を2回実行すると次のようになります。 context.next/context.prevを使ってステータスを管理することで、ネストが深くなるのを防いでいます。ですが、switchで使っている数字は非同期処理が追加されるごとに数字が増えていきます。Babelの生成したコードを読み取るのは大変になっていくことでしょう。
なお、Promiseの場合はrejectを使いますが、awaitを使った場合はtry/catchでエラー処理を行います。
非同期処理はJavaScriptに付きもので、一番厄介な存在でしょう。しかしES7のawaitによってネストがなくなったり、変数を同じスコープで扱えるようになります。現在、デスクトップやスマートフォンのほとんどのブラウザでサポートされていますので(IE系は未サポート)、HTML5を活用する際にはぜひ使ってみてください。