動機
WebpackでRiot.jsをトランスパイルする雛形はなんとなく出来たのですが、非同期を扱い始めるとPromiseだけではやはり苦しい。async/await せめて、co/yeldを使いたい。
いまいち正解がわからず試行錯誤右往左往したので後々のためにメモです。
フロントエンド周りは1年前の情報だと疑ってかからないとハマるというつらい世界ですね。
Webpackの設定
plugins: ["transform-regenerator", "transform-runtime"]
この2つのbabel-pluginを追加です。
es2015-riot には transform-regenerator が含まれている
しかしブラウザで動かすためには transform-runtimeが必要
試してみる
サンプルはこちらです。
https://github.com/NewGyu/riot-sample/tree/async-await
npm start
して http://localhost:8080 でためせます。
async.tag
<async-page>
<button class="button { is-loading: yielding }" onclick={ testGeneratorYield }>generator,yield</button>
<button class="button { is-loading: awaiting }" onclick={ testAsyncAwait }>async,await</button>
<div id="notify-area"></div>
<script>
async testAsyncAwait(e) {
this.update({awaiting: true});
const r = await asyncFunc();
riot.mount("#notify-area", "message-notify", {text: r});
this.update({awaiting: false});
}
testGeneratorYield(e) {
const self = this;
co(function*(){
self.update({yielding: true});
const r = yield generatorFunc();
riot.mount("#notify-area", "message-notify", {text: r});
self.update({yielding: false});
})
}
</script>
</async-page>
export function* generatorFunc() {
yield waitFor(2);
return "generator";
}
export async function asyncFunc() {
await waitFor(3);
return "async";
}
function waitFor(sec) {
return new Promise((res, rej) => {
setTimeout(res, 1000*sec);
});
}
いずれかのボタンを押すと、2,3秒後にメッセージが表示されるという単純なものです。
async/awaitの方がタイプ数少なく書けますね。