MatAtBread / fast-async

605 stars 21 forks source link

for ... of produces `Cannot read property 'length' of undefined` error #50

Closed olebedev closed 6 years ago

olebedev commented 6 years ago

However, [this](http://nodent.mailed.me.uk/#async%20function%20on(id%2C%20cbk)%20%7B%0A%20%20%20%20if%20(!id%20%7C%7C%20!cbk)%20%0A%20%20%20%20%20%20%20%20return%3B%0A%20%20%20%20for%20(const%20sub%20of%20this.subs)%20%7B%7D%0A%20%20%20%20%2F%2F%20%20%20if%20(sub.id%20%3D%3D%3D%20id%20%26%26%20sub.cbk%20%3D%3D%3D%20cbk)%20return%20sub%3B%0A%20%20%20%20const%20sub%20%3D%20new%20Subscription(this%2C%20id%2C%20cbk)%3B%0A%20%20%20%20this.subs.push(sub)%3B%0A%20%20%20%20await%20sub.on()%3B%0A%20%20%20%20return%20sub%3B%0A%7D~options~%7B%22mode%22%3A%22promises%22%2C%22promiseType%22%3A%22Zousan%22%2C%22noRuntime%22%3Atrue%2C%22es6target%22%3Afalse%2C%22wrapAwait%22%3Atrue%2C%22spec%22%3Atrue%7D) code is valid. I don't know why, but my own local setup doesn't compile it.

Content of package.json:

{
  "name": "fast-test",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "build": "babel -d lib src"
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-plugin-transform-es2015-spread": "^6.22.0",
    "babel-plugin-transform-flow-strip-types": "^6.22.0",
    "babel-plugin-transform-object-rest-spread": "^6.26.0",
    "babel-preset-es2015": "^6.24.1",
    "fast-async": "^6.3.0"
  }
}

Content of .babelrc:

{
  "presets": [
    "es2015"
  ],
  "plugins": [
    [
      "fast-async",
      {
        "env": {
          "log": false
        },
        "compiler": {
          "promises": true,
          "generators": false
        },
        "runtimePattern": "directive",
        "useRuntimeModule": false
      }
    ],
    "transform-flow-strip-types",
    "transform-es2015-spread",
    "transform-object-rest-spread"
  ]
}

Content of src/index.js:

async function on(id, cbk) {
  if (!id || !cbk) return;
  for (const sub of this.subs) {
    if (sub.id === id && sub.cbk === cbk) return sub;
  }

  const sub = new Subscription(this, id, cbk);
  this.subs.push(sub);
  await sub.on();
  return sub;
}

And the output is:

△ ~/Projects/fast-test yarn build
yarn run v1.3.2
$ babel -d lib src
TypeError: src/index.js: Cannot read property 'length' of undefined
    at Buffer._append (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/buffer.js:100:26)
    at Buffer.append (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/buffer.js:72:10)
    at Generator._append (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/printer.js:206:52)
    at Generator.word (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/printer.js:131:10)
    at Generator.Identifier (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/generators/types.js:38:8)
    at /Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/printer.js:298:23
    at Buffer.withSource (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/buffer.js:159:28)
    at Generator.withSource (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/printer.js:189:15)
    at Generator.print (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/printer.js:297:10)
    at Generator.printJoin (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/printer.js:366:12)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

What I am doing wrong?


I've added workaround into babel-generator and the result we surprised for me. Here to finction above, complied by babel in command line:

function on(id, cbk) {
  return new Promise(function ($return, $error) {
    var $Try_1_Finally = function ($Try_1_Exit) {
      return function ($Try_1_Value) {
        var $Try_2_Finally = function ($Try_2_Exit) {
          return function ($Try_2_Value) {
            if (_didIteratorError) {
              throw _iteratorError;
            }

            return $Try_2_Exit && $Try_2_Exit.call(this, $Try_2_Value);
          }.$asyncbind(this, $error);
        }.$asyncbind(this);

        var $Try_2_Catch = function ($exception_3) {
          throw $exception_3;
        }.$asyncbind(this, $Try_2_Finally($error));
        try {
          if (!_iteratorNormalCompletion && _iterator.return) {
            _iterator.return();
          }

          return $Try_2_Finally()();
        } catch ($exception_3) {
          $Try_2_Catch($exception_3)
        }

        return $Try_1_Exit && $Try_1_Exit.call(this, $Try_1_Value);
      }.$asyncbind(this, $error);
    }.$asyncbind(this);

    var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _sub, sub;

    if (!id || !cbk) return $return();
    _iteratorNormalCompletion = true;
    _didIteratorError = false;
    _iteratorError = undefined;
    var $Try_1_Post = function () {

      sub = new Subscription(this, id, cbk);
      this.subs.push(sub);
      return sub.on().then(function ($await_11) {
        return $return(sub);
      }.$asyncbind(this, $error), $error);
    }.$asyncbind(this, $error);var $Try_1_Catch = function (err) {
      _didIteratorError = true;
      _iteratorError = err;
      return $Try_1_Finally($Try_1_Post)();
    }.$asyncbind(this, $Try_1_Finally($error));
    try {
      for (_iterator = this.subs[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
        _sub = _step.value;

        if (_sub.id === id && _sub.cbk === cbk) return $Try_1_Finally($return)(_sub);
      }return $Try_1_Finally($Try_1_Post)();
    } catch (err) {
      $Try_1_Catch(err)
    }
  }.$asyncbind(this));
}

Compare it with nodent.mailed.me.uk's result, the difference is a huge. The question is, why so? And, how to setup babel to have a nice output like from nodent.mailed.me.uk ?

/cc @MatAtBread

matAtWork commented 6 years ago

It looks like babel is applying it's own async transform before using fast-async. I'm not a babel expert, but what happens if you re-order your devDependencies, eg:

 "devDependencies": {
    "fast-async": "^6.3.0",
    "babel-cli": "^6.26.0",
    "babel-plugin-transform-es2015-spread": "^6.22.0",
    "babel-plugin-transform-flow-strip-types": "^6.22.0",
    "babel-plugin-transform-object-rest-spread": "^6.26.0",
    "babel-preset-es2015": "^6.24.1"
  }
matAtWork commented 6 years ago

@olebedev I'm guessing you found a resolution to this issue, so I'll close for now. Please re-open if necessary