Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async function that holds super #231

Closed
zhanzhenzhen opened this issue Jan 17, 2016 · 2 comments
Closed

Async function that holds super #231

zhanzhenzhen opened this issue Jan 17, 2016 · 2 comments
Assignees

Comments

@zhanzhenzhen
Copy link

The problem is when the async function is a class method (or is inside a class method) that holds super. For example:

class A {
  m() {}
}
class B extends A {
  async m() {
    await foo();
    super.m(1);
  }
}

But the generated JS is illegal:

class A {
  m() {}
}
class B {
  m() {
    return regeneratorRuntime.async(function _callee$(_context) {
      while (1) switch (_context.prev = _context.next) {
        case 0:
          _context.next = 2;
          return regeneratorRuntime.awrap(foo());

        case 2:
          super.m(1);

        case 3:
        case "end":
          return _context.stop();
      }
    }, null, this);
  }
}

The reason is that I found the ES6 spec prohibits a non-arrow function (unless it's a method function) from holding super. So modifying the inner function to arrow will solve the problem:

class A {
  m() {}
}
class B {
  m() {
    return regeneratorRuntime.async(_context => {
      while (1) switch (_context.prev = _context.next) {
        case 0:
          _context.next = 2;
          return regeneratorRuntime.awrap(foo());

        case 2:
          super.m(1);

        case 3:
        case "end":
          return _context.stop();
      }
    }, null, this);
  }
}

So I suggest that Regenerator give us an option to output it in arrow function. Because for this case, we even can't use the more simple "generator-to-async" transformer because it will produce:

m() {
  return _asyncToGenerator(function* () {
    yield foo();
    super.m(1);
  })();
}

which is also illegal. So a thing like Regenerator is a must, until the async function is natively supported, maybe in 2017.

BTW, I'm not quite sure if this is legal in ES7:

m() {
  (async () => {
    await foo();
    super.m(1);
  })();
}

though I guess it's legal.

It can be better to also have an option to output "use strict" on top of the generated code, because the use case is not limited to 6-5, but also 7-6.

@hilkeheremans
Copy link

Yes, I'm experiencing the exact same issue, unfortunately.

@benjamn
Copy link
Collaborator

benjamn commented Jan 25, 2016

Another option would be to transform super.m(...) to A.prototype.m.call(this, ...).

I assume you can't have an async constructor() {...} method, can you?

@benjamn benjamn closed this as completed in 1c0f5c5 Dec 1, 2016
@benjamn benjamn self-assigned this Dec 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants