babelのAsyncIterationバグ
問題
for-await-ofのボディで配列への分割代入を行うと、
Cannot read property 'file' of undefined
というエラーを投げてトランスパイルに失敗する。
どうやらscopeの解析に失敗しているらしい。
サンプルコード
async function g(t) { return new Promise(r => setTimeout(() => r([true]), t)); } async function r() { for await (const t of [1000, 2000, 3000]) { const [result] = await g(t); } } r();
package.json
"dependencies": { "babel-cli": "^6.24.1", "babel-plugin-transform-async-generator-functions": "^6.24.1", "babel-plugin-transform-regenerator": "^6.24.1", "babel-plugin-transform-runtime": "^6.23.0", "babel-polyfill": "^6.23.0", "babel-preset-es2015": "^6.22.0", "babel-preset-stage-3": "^6.24.1", "babel-runtime": "^6.23.0" }, "babel": { "plugins": [ [ "transform-runtime", { "helpers": false, "polyfill": false, "regenerator": true, "moduleName": "babel-runtime" } ] ], "presets": [ "es2015", "stage-3" ] }
解決
とりあえずbugとしてbabel側にはissueを立てておいた。
現状で取れる選択肢
配列ではなくオブジェクト形式で受け取る
データ構造の変更が必要だがまあ許容できるか?
async function g(t) { return new Promise(r => setTimeout(() => r({result: true}), t)); } async function r() { for await (const t of [1000, 2000, 3000]) { const {result} = await g(t); } } r();
分割代入で受け取らない
その後にインデックスアクセスしなければならないのでちょっと面倒
async function g(t) { return new Promise(r => setTimeout(() => r([true]), t)); } async function r() { for await (const t of [1000, 2000, 3000]) { const result = await g(t); } } r();
まとめ
はやく直ってくれると嬉しい