-2

Consider the following snippet:

class Foo {
  method = () => {
    console.log('method');
  }
}
const f = new Foo();
f.method();

Works just fine. But, if the function is made async instead, with no other changes:

class Foo {
  method = async () => {
    console.log('method');
  }
}
const f = new Foo();
f.method();

This results in a syntax error. It occurs regardless of whether an arrow function is used:

class Foo {
  method = function() {
    console.log('method');
  }
}
const f = new Foo();
f.method();

class Foo {
  method = async function() {
    console.log('method');
  }
}
const f = new Foo();
f.method();

Is my syntax somehow incorrect, or are async functions simply prohibited in class fields?

(Of course, a plain async method on the prototype is possible too, but I'm asking why/how async functions in class fields can work)

Taking the comment's suggestion of async method() => { doesn't work either:

class Foo {
  async method() => {
    console.log('method');
  }
}
const f = new Foo();
f.method();
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Snow
  • 3,820
  • 3
  • 13
  • 39
  • 2
    You should definitely mention in the question that you have the **Use Babel** enabled in your snippets. Your code works fine without it. `Uncaught SyntaxError: Inline Babel script: Unexpected token (3:20)` – Tyler Roper Feb 22 '19 at 02:53

3 Answers3

3

Can async functions be in class fields?

Yes.

//Without BabelJS / ES2015
class Foo {
  method = async () => {
    console.log('method');
  }
}
const f = new Foo();
f.method();

Can async functions be in class fields when using an ES2015 transpiler?

No.

//Without BabelJS / ES2015
class Foo {
  method = async () => {
    console.log('method');
  }
}
const f = new Foo();
f.method();

async was introduced with ECMAScript 2017 (ECMA-262).

In your snippets, you have Use Babel / ES2015 enabled, which predates async.

Tyler Roper
  • 21,445
  • 6
  • 33
  • 56
  • So the transpiler supports class fields, even though they're only at Stage 3, (maybe they'll be integrated in ES2020?) while `async` is not supported, despite being in the spec for quite a while now? That's surprising, I would have expected it to be the other way around. It looks like the transpiler doesn't support *ordinary async functions* either. – Snow Feb 22 '19 at 03:11
  • I agree with you on the inconsistencies, but I don't have a great answer for that unfortunately. *If I had to guess*, it's using a Babel plugin that allows class properties (which at the time was in **Stage 1**), as discussed [in this article from 2016](https://medium.com/@joshblack/writing-a-react-component-in-es2015-a0b27e1ed50a). – Tyler Roper Feb 22 '19 at 03:14
2

Q: Would this work for you:

class Foo {
  async method () {
    console.log('method');
  }
}
const f = new Foo();
f.method();
paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • 1
    That's not using a class field, though - I'm asking what's wrong with my implementation. I'm well aware of how to use a normal method in a class – Snow Feb 22 '19 at 02:36
1

According to mozilla this syntax is not supported in IE which im gussing that your are getting the error there, your second example work greet in chrome.

class Foo {
  method = async () => {
    console.log('method');
  }
}
const f = new Foo();
f.method();
Alen.Toma
  • 4,684
  • 2
  • 14
  • 31
  • All of the snippets are being transpiled. If you open this page on Internet Explorer, you will see the first and third snippets working as desired. – Snow Feb 22 '19 at 02:53
  • tested the above at IE 11 and it did not work, and if you read Browser compatibility you will see that the syntax dose not support IE – Alen.Toma Feb 22 '19 at 02:55
  • 2
    @Alen.Toma OP is using a transpiler (Babel) specifically *because* of browser compatibility. That's what a transpiler does. – Tyler Roper Feb 22 '19 at 03:00
  • @Alen.Toma See my screenshot in IE: it works as expected https://i.stack.imgur.com/OUxip.png – Snow Feb 22 '19 at 03:00