(ES6) class (ES2017) async / await getter
Asked Answered
S

4

85

Is it or will it be possible to have an ES6 class getter return a value from an ES2017 await / async function.

class Foo {
    async get bar() {
        var result = await someAsyncOperation();

        return result;
    }
}

function someAsyncOperation() {
    return new Promise(function(resolve) {
        setTimeout(function() {
            resolve('baz');
        }, 1000);
    });
}

var foo = new Foo();

foo.bar.should.equal('baz');
Statampere answered 23/11, 2015 at 19:47 Comment(6)
This is all you need: get bar(){ return someAsyncOperation(); }Puke
@FelixKling I updated my post to hopefully clarify my question. I am not trying to return a function from the getter. I want the return value to come from an async operation.Statampere
Yes, return someAsyncOperation(); returns the promise that someAsyncOperation returns. It doesn't return a function (what made you think that?)Puke
I understand return someAsyncOperation(); would return a promise. I want to return the result of the promise. foo.bar should return 'baz'Statampere
It can't. You cannot return synchronously from an asynchronous function. async/await is just syntactic sugar around promises + generators. It lets you write code that looks synchronous, but it still runs asynchronously. At the top level you still have to deal with the promise. You might be able to do await foo.bar, but if not, you have to deal with the promise returned by foo.bar directly.Puke
It would be nice if you could just do: get async functionName(){}. I'd like the ability to await inside of a getter (directly) instead of the round-about ways answered here.Superphosphate
H
71

Update: As others have pointed out, this doesn't really work. @kuboon has a nice workaround in an answer below here..

You can do this

class Foo {
    get bar() {
        return (async () => {
            return await someAsyncOperation();
        })();
    }
}

which again is the same as

class Foo {
    get bar() {
        return new Promise((resolve, reject) => {
            someAsyncOperation().then(result => {
                resolve(result);
            });
        })
    }
}
Hebephrenia answered 8/9, 2016 at 10:0 Comment(3)
No, it won't return a result as Enki asked, but promiseAlvord
This is exactly same to get bar(){ return someAsyncOperation() }Limon
Or class Foo { get bar() { return (async () => await someAsyncOperation)() } }Maryjomaryl
L
25

You can get the value by await on the caller side.

class Foo {
    get bar() {
        return someAsyncOperation();
    }
}
async function test(){
  let foo = new Foo, val = await foo.bar;
  val.should.equal('baz');
}
Limon answered 9/11, 2018 at 5:27 Comment(0)
A
15

You can only await promises, and async functions will return promises themselves.
Of course a getter can yield such a promise just as well, there's no difference from a normal value.

Aficionado answered 23/11, 2015 at 19:49 Comment(0)
C
2

For the value returned by the getter, this changes nothing, since an async function returns a Promise anyway. Where this matters, is in the function, since await can only be used in an async function.

If the issue it that await is wished in the function, I would do:

get property () {
  const self = this; // No closure with `this`, create a closure with `self`.
  async function f () { // `async` wrapper with a reference to `self`
    const x = await self.someFunction(); // Can use `await`
    // the rest with “self” in place of “this”
    return result;
  }
  return f(); // Returns a `Promise` as should do an `async get`
}
Columbous answered 21/4, 2020 at 23:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.