async-await

(2016/05/01〜2016/08/16)
  • 非同期処理を同期的に書ける

  • たぶんES2015じゃないけどbabelで使える
  • ES7らしい
  • 準備

  • babelで使うにはbabel-preset-stage-0が必要
  • $ npm install babel babel-preset-stage-0 -save
  • .babelrcに設定
  • json
  • { "presets": [ "es2015", "stage-0" ] }
  • regenerator-runtimeを読み込む
  • myapp.js
  • import "babel-regenerator-runtime";
  • babel-polyfillをimportしてもいい
  • async-await使いたいだけならregenerator-runtimeだけでいい
  • 使い方

  • function宣言の前にasyncキーワードが必要
  • await Promiseするとそこで処理をブロックしてくれる
  • なので非同期処理はコールバックじゃなくPromiseで実装してあると非常にありがたい
  • 例:axiosというPromiseで結果を返してくれるHTTPクライアントを使う
  • javascript
  • async function foo(url){
  • const res = await axios.get(url);
  • return res.body;
  • }
  • 以下、便利な使い方の例

  • コールバックではないので簡潔に書ける
  • cacheが無ければDBから読む

  • javascript
  • const page = await pageCache.get(title) || this.findOne({title});
  • 無ければ、をORで書ける
  • 普通はコールバック2段になって地獄になる
  • cacheとDBどっちも非同期処理で見に行っている
  • オブジェクトの宣言に非同期処理を混ぜれる

  • javascript
  • const place = {
  • name: "横浜",
  • events: {
  • yokohamaArena: await arena.getEvents()
  • },
  • forecast: await forecast.get("横浜")
  • }
  • この書き方だとgetEventsしてからforecastを取得、と順番に行われる
  • 同時に実行させたければPromise.allを使う

  • Promiseを配列で渡すと、同時に並列実行してくれる
  • 全部終わったらresolveするPromiseを返してくれるので、それをawaitする
  • javascript
  • const result = await Promise.all([arena.getEvents(), forecast.get("横浜")]);
  • result[0] // 横浜アリーナのイベント
  • result[1] // 天気
  • ちょっと待つ

  • 自分で書かないでBluebird.delayとか使ってもいい
  • javascript
  • const delay = async msec => new Promise(resolve => setTimeout(resolve, msec));
  • async function foo(){
  • cosnole.log("foo");
  • delay(1000); // 1000msec待機
  • console.log("bar");
  • delay(500);
  • console.log("baz");
  • }