rjcarr
rjcarr

Reputation: 2091

Chaining callbacks and retaining 'this' in javascript

I'm basically trying to chain functions using callbacks but still preserve the original meaning of 'this'. So, say I have a simple function that takes a callback function and responds with results:

function simple(callback) {
    var s = do something ...
    callback(s);
}

And then I have some prototype functions where I need access to the 'this' object at the end of the chain. I want f1 to call f2 which calls simple yet sends the results to f3. Here's how you would naively do it:

A.prototype.f1 = function() {
    this.f2(this.f3);
}

A.prototype.f2 = function(callback) {
    simple(callback);
}

A.prototype.f3 = function(result) {
    // need access to 'this' object, e.g., 
    var a = this.a;
    var b = this.b; 
    ...
}

The problem is by the time you get to f3 the 'this' is no longer the object you think it is (it's the global object). So is there any solution to this? I have actually come up with a solution but it seems extremely crude and wanted to see if I'm missing something obvious.

Note that there are probably ways to move names around to make things more clear, but I can't simply call f3 from f2 or anything like that ... I really need to keep things as in the example.

Thanks for taking a look.

EDIT: The answer is to use bind as has been pointed out below. Thanks for the help! I thought I'd share my "crude" solution as an exercise, though (everything else is the same):

A.prototype.f1 = function() {
    this.f2("f3");
}

A.prototype.f2 = function(funcname) {
    var that = this;
    simple(function(result) { that[funcname](result); });
}

I should note that it worked, and the only limitation (besides being ugly) was the callback function had to a member of the current object (which wasn't a problem). Thanks again for the help!

Upvotes: 2

Views: 723

Answers (2)

Shawn31313
Shawn31313

Reputation: 6052

Change your f1 function to the following:

A.prototype.f1 = function () {
    this.f2(this.f3.bind(this));
}

The bind function allows you to specify the value of this. Check out this example.

Upvotes: 1

rossipedia
rossipedia

Reputation: 59387

Have a look into Function.bind. It binds a specific value to this when the function is called.

Upvotes: 1

Related Questions