Search code examples
javascriptnode.jses6-promise

Awaiting an event completion in NodeJS before returning


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.


Solution

  • 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);