3

In NodeJS, I have an object like,

var scope = { word: "init" };

Using Object.defineProperty as described in MDN I re-write the get() function to be like this,

Object.defineProperty(scope, 'word', {
  get: function() {
    return Math.random();
  }
});

Which correctly returns a new random each time I scope.word in the console. However the function must also get data from a function with a callback. So it works pretty much like a setTimeout,

Object.defineProperty(scope, 'word', {
  get: function() {
    setTimeout(() => {
      return Math.random();
    }, 1000)
  }
});

Now everytime I do scope.word I get,

undefined

Because the get() function is synchronous. This can be of course solved by returning a Promise,

Object.defineProperty(scope, 'word', {
  get: function() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(Math.random());
      }, 1000)
    });
  }
});

But then I would need to do scope.word.then(...) but the whole idea behind what we are building is that the developer only has to scope.word like if it was a plain easy-to-use variable. Like an Angular's $scope or a VUE.js 'data'.

How can I make the get() function return an actual value, not a Promise? Is it possible to workaround using async / await? How?

adelriosantiago
  • 7,762
  • 7
  • 38
  • 71
  • Just out of curiosity why do you need it to make an asynchronous function ?. Do you read that value from database or a http call ? – Saroj Feb 26 '19 at 08:57
  • 2
    Using `async`/`await` won't _really_ help you. It will remove the `.then` but then you'd need to get your property like so every time: `await scope.word`. This may seem easier, but you also have to keep in mind that in order to use `await` it must be used within an `async` function. Something like this: https://jsfiddle.net/v7ohbsfx/ – Nick Parsons Feb 26 '19 at 09:01
  • 2
    async/await is just a syntactic sugar. It will be something like `async function yourFunction() { var word = await scope.word; }` – adiga Feb 26 '19 at 09:02
  • this question also addresses the same requirement .https://stackoverflow.com/questions/11843619/async-function-in-getter-w-return-in-callback – Saroj Feb 26 '19 at 09:04
  • Possible duplicate of [Promises and async/await in nodejs](https://stackoverflow.com/questions/52641327/promises-and-async-await-in-nodejs) and [Using async await on custom promise](https://stackoverflow.com/questions/46514570) and [Changing my callbacks, promise to async await](https://stackoverflow.com/questions/53607365) – adiga Feb 26 '19 at 09:05
  • Possible duplicate of [Async Function in Getter w/ Return in Callback](https://stackoverflow.com/questions/11843619/async-function-in-getter-w-return-in-callback) – jo_va Feb 26 '19 at 09:08
  • 1
    No. You cannot get away with a returned promise without calling a CB or `await`. – Charlie Feb 26 '19 at 09:36

1 Answers1

-1

One of the solutions is to pass the callback function like this.

    const scope = {}
    Object.defineProperty(scope, 'word', {
      value: (cb)=>{
         setTimeout(() => {
              cb(Math.random())
          }, 1000)
      }
    });

    scope.word(res=>console.log(res))
DedaDev
  • 4,441
  • 2
  • 21
  • 28