Asynchronous JavaScript and object permanence
I have JS code roughly like this:
function myObject()
{
this.a = 13;
this.fetchData = function()
{
alert(this.a);
getData(this.processData);
开发者_开发技巧}
this.processData = function(data)
{
// do stuff with data
alert(this.a);
}
this.fetchData();
}
function getData(callback)
{
// do async request for data and call callback with the result
}
My problem is: The function fetchData has access to my a variable via the this keyword, but the other function processData does not when called by getData. I understand why this happens, but don't know how to work around it.
How would you approach this problem preferably in OOP style? (The function getData has to be available to multiple classes)
Two options:
1) Have getData
accept a context parameter (usually called context
or thisArg
) and use callback.apply(context, ...)
or callback.call(context, ...)
to call it. So:
function getData(callback, context) {
// ...when it's time to call it:
callback.call(context, arg1, arg2);
// or
callback.apply(context, [arg1, arg2]);
}
2) Create a function that, when called, will turn around and call the original callback with this
set to the correct value. (This is sometimes called "binding".)
For example, using an explicit closure:
this.fetchData = function()
{
var self = this;
alert(this.a);
getData(getDataCallback);
function getDataCallback(arg1, arg2) {
self.processData(arg1, arg2);
}
}
Or have a generic bind
function to do it (which will also involve a closure, but in a nice controlled context so it's not closing over stuff you don't need). See link below for an example of a simple bind
function.
More: You must remember this
I think that you only need to define "a" as a local variable so that it is in the cope of both fetchData and getData, something like this:
function myObject() {
var a = 13;
this.fetchData = function() {
alert(a);
getData(this.processData);
}
this.processData = function(data) {
// do stuff with data
alert(a);
}
this.fetchData();
}
You could also do,
function myObject() {
this.a = 13;
var that = this;
this.fetchData = function() {
alert(that.a);
getData(this.processData);
}
this.processData = function(data) {
// do stuff with data
alert(that.a);
}
this.fetchData();
}
精彩评论