abcdefGets

ゲッツ!

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を立てておいた。

github.com

現状で取れる選択肢

配列ではなくオブジェクト形式で受け取る

データ構造の変更が必要だがまあ許容できるか?

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();

まとめ

はやく直ってくれると嬉しい