Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

“await this.method();” doesn’t work in static method

I know of the ES6 await feature and I’d like to use it in a function I created in a class.

It works well, but when the function is a static function, it doesn’t. Is there any reason for that? Also, what will be the right way to be able to use await inside a static function?

class MyClass {
  resolveAfter2Seconds() {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve('resolved');
      }, 2000);
    });
  }

  static async asyncCall() {
    console.log('calling');
    var result = await this.resolveAfter2Seconds();
    console.log(result);
    // expected output: "resolved"
  }
}

MyClass.asyncCall();
like image 281
John David Avatar asked Apr 03 '18 00:04

John David


2 Answers

You can use await just fine in a static function. That is not your issue.

BUT, this in a static function is MyClass so this.someMethod() is looking for another static method, not an instance method and resolveAfter2Seconds() is an instance method, not a static method so this.resolveAfter2Seconds() won't find that method because that's like calling MyClass.resolveAfter2Seconds() which doesn't exist.

If you also make resolveAfter2Seconds() be static, then it would probably work because this inside asyncCall() is MyClass so this.resolveAfter2Seconds() is looking for another static method.

This should work where you make resolveAfter2Seconds also be static:

class MyClass {

  static resolveAfter2Seconds() {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve('resolved');
      }, 2000);
    });
  }

  static async asyncCall() {
    console.log('calling');
    var result = await this.resolveAfter2Seconds();
    console.log(result);
    // expected output: "resolved"
  }
}

Or, you could reach into the prototype and call it from there because it is actually a static method (doesn't reference this at all):

  static async asyncCall() {
    console.log('calling');
    var result = await MyClass.prototype.resolveAfter2Seconds();
    console.log(result);
    // expected output: "resolved"
  }
like image 155
jfriend00 Avatar answered Nov 15 '22 05:11

jfriend00


You're calling await this.resolveAfter2Seconds(); as if the this was an instantiation of MyClass, but in the context that your'e calling it, it isn't - resolveAfter2Seconds is a method on the prototype of MyClass, it's not a property of the class itself. Call the prototype method instead:

class MyClass {
  resolveAfter2Seconds() {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve('resolved');
      }, 2000);
    });
  }
  static async asyncCall() {
    console.log('calling');
    var result = await this.prototype.resolveAfter2Seconds();
    console.log(result);
    // expected output: "resolved"
  }

}
MyClass.asyncCall();
like image 3
CertainPerformance Avatar answered Nov 15 '22 06:11

CertainPerformance