JavaScript
babel

Babel 6.7 で async/await する

More than 1 year has passed since last update.

Babel 6 から preset が必要になったので、若干の注意が必要。

謝辞

編集リクエストを通じて @armorik83 さんに記事を改善していただきました。ありがとうございます!

環境

$ node -v
v5.10.1

$ node_modules/.bin/babel --version
6.7.7 (babel-core 6.7.7)

準備

npm i -S babel-polyfill
npm i -D babel-preset-es2015 babel-preset-stage-3

2016-04-24 現在、async/await は ECMAScript 策定段階において Stage 3 であるため、Stage 3 用の preset を導入する必要がある(ここでは ES2015 用の preset も同時にインストールしている)。

また、babel-polyfill をインストールしておかないと、regeneratorRuntime が見つからないと後で怒られる。

なお、 npm i -Snpm install --save と、 npm i -Dnpm install --save-dev と等価。

これらのインストールが終わったら、バベる際に用いる preset を .babelrc に明記する必要がある。

.babelrc
{
  "presets": [ "es2015", "stage-3" ]
}

.babelrc の場所は、プロジェクトのルートディレクトリで構わない。別の方法として、package.json の babel プロパティに明記する方法もある。

package.json
{
  // ...
  "babel": {
    "presets": [ "es2015", "stage-3" ]
  }
}

上記の package.json はあくまでも例示のためであり、JSON の文法にコメントは存在しないので注意されたい。

使ってみる

mizchi さんの Babelのasync/await試してみた(+中の処理をちょっと追ってみた) を参考にし、簡単なコードを書いてみる。

async.babel
import 'babel-polyfill';

const wait = (n) => {
  return new Promise((done) => setTimeout(() => done(n), n));
};

const main = async () => {
  await wait(1000);
  console.log('await done');
};

wait(2000).then((n) => console.log(`promise normaly done: ${n}`));

main();

上記の async.babel を async.js にバベって実行してみる。

$ node_modules/.bin/babel async.babel -o async.js
$ node async.js
await done
promise normaly done: 2000

最後の2行が1秒差で表示されるはずである。

参考サイト