how to solve 'this' problems with node libraries like async and request

I've written a node script that gets some data by requesting REST API data (using the library request). It consists of a couple of functions like so:

var data = { /* object to store all data */ },
function getKloutData() {
  request(url, function() { /* store data */}
}
// and a function for twitter data

Because I want to do some stuff after fetching all the I used the library async to run all the fetch functions like so:

async.parallel([ getTwitterData, getKloutData ], function() {
    console.log('done');
});

This all works fine, however I wanted to put everything inside a object pattern so I could fetch multiple accounts at the same time:

function Fetcher(name) { 
    this.userID = ''
    this.user = { /* data */ }
    this.init();
}
Fetcher.prototype.init = function() {
    async.parallel([ this.getTwitterData, this.getKloutData ], function() {
        console.log('done');
    });
}
Fetcher.prototype.getKloutData = function(callback) {
    request(url, function () { /* store data */ });
};

This doesn't work because async and request change the this context. The only way I could get around it is by binding everything I pass through async and request:

Fetcher.prototype.init = function() {
    async.parallel([ this.getTwitterData.bind(this), this.getKloutData.bind(this) ], function() {
        console.log('done');
    });
}
Fetcher.prototype.getKloutData = function(callback) {
    function saveData() {
        /* store data */
    }


    request(url, saveData.bind(this);
};

Am I doing something basic wrong or something? I think reverting to the script and forking it to child_processes creates to much overhead.

You're doing it exactly right.

The alternative is to keep a reference to the object always in context instead of using bind, but that requires some gymnastics:

Fetcher.prototype.init = function() {
    var self = this;
    async.parallel([
        function(){ return self.getTwitterData() },
        function(){ return self.getKloutData() }
    ], function() {
        console.log('done');
    });
}

Fetcher.prototype.getKloutData = function(callback) {
    var self = this;

    function saveData() {
        // store data
        self.blah();
    }

    request(url, saveData);
};

You can also do the binding beforehand:

Fetcher.prototype.bindAll = function(){
    this.getKloutData = this.prototype.getKloutData.bind(this);
    this.getTwitterData = this.prototype.getTwitterData.bind(this);
};

Fetcher.prototype.init = function(){
    this.bindAll();
    async.parallel([ this.getTwitterData, this.getKloutData ], function() {
        console.log('done');
    });
};

You can save this into another variable:

var me = this;

Then me is your this.

Instantiate object with this function:

function newClass(klass) {
    var obj = new klass;

    $.map(obj, function(value, key) {
        if (typeof  value == "function") {
            obj[key] = value.bind(obj);
        }
    });

    return obj;
}

This will do automatic binding of all function, so you will get object in habitual OOP style, when methods inside objects has context of its object.

So you instantiate you objects not through the:

var obj = new Fetcher();

But:

var obj = newClass(Fetcher);