0

I have a class getter that I want to return a value from only when an event listener has completed. Is there a way to do this?

I am aware that I can wrap it in a Promise and apply it to the chain but it does not follow the modularisation I require the the usage of the application:

class Request{
    get body(){
        console.log('processed before')
        console.log(processed)
        this._request.on('data', chunk => {
                console.log('data received');
                if (null == this._body._text) {
                    this._body._text = "";
                }
                this._body._text += chunk;
            })
            .once('end', () => {
                console.log('processed')
                processed = true;
            });
        console.log('processed after')
        console.log(processed)

        console.log('return this._body')
        return this._body;
    }
}

let req = new Request();
console.log(req.body());

I need the return to only continue and return after the request "end" event has occurred.

Thank-you in advance.

2 Answers2

0

You could generally use async functions here:

async function run(){
 console.log('processed before');
 console.log(processed);

 var processed = await new Promise(function(processed){
 this._request.on('data', chunk => {
        console.log('data received');
        this._body._text = "";
        this._body._text += chunk;
 })
 .once('end', () => {
        console.log('processed')
        processed(true);       
  });
 });

 console.log('processed after');
 console.log(processed);

 console.log('return this._body')
 return this._body;
}

However it is very inefficient to really halt and await execution, thats why it isnt possible in js ( await is just a beautiful .then ), and the async function actually retunrs a promise. So using it as a getter wont work and is a terrible way of doing so. You probably need a non getter approach, or the getter returns the promise:

var obj = {
 get stuff(){
   return run();
 }
};

obj.stuff.then(console.log);
obj.stuff.then(console.log);
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • The main intentention of blocking the thread was to make the use of the module easier as the body would always need to be parsed before being accessed. As an alternative, I guess the best idea for me is to create a parseBody method that hydrates the body and returns a Promise to run from in the chain. – Thomas McFarlane Aug 05 '17 at 16:15
  • @thomas McFarlane somemodule.createBody.then(body=>) – Jonas Wilms Aug 05 '17 at 16:16
  • Yeah - that is likely the approach I will take. Have it call with hydration Promise and then continue in the chain. – Thomas McFarlane Aug 05 '17 at 16:20
0

If modularity is a concern, you could try using events. I think a promise based workflow is probably more recommended, and idiomatic, but event based work flows can work. Essentially, you add a line to your promise that emits an event on resolution, and have your callback function listening for that event to transmit. Its the type of flow you might see in mobile apps.

That said, I think the promise approach is probably better, but if it's not workable events might be.

TheCog19
  • 1,129
  • 12
  • 26