JavaScript setInterval y "esta" solución
Necesito acceder this
desde mi setInterval
controlador
prefs: null,
startup : function()
{
// init prefs
...
this.retrieve_rate();
this.intervalID = setInterval(this.retrieve_rate, this.INTERVAL);
},
retrieve_rate : function()
{
var ajax = null;
ajax = new XMLHttpRequest();
ajax.open('GET', 'http://xyz.example', true);
ajax.onload = function()
{
// access prefs here
}
}
¿Cómo puedo this.prefs
acceder ajax.onload
?
this.intervalID = setInterval(this.retrieve_rate.bind(this), this.INTERVAL);
La línea setInterval debería verse así:-
this.intervalID = setInterval(
(function(self) { //Self-executing func which takes 'this' as self
return function() { //Return a function in the context of 'self'
self.retrieve_rate(); //Thing you wanted to run as non-window 'this'
}
})(this),
this.INTERVAL //normal interval, 'this' scope not impacted here.
);
Editar : El mismo principio se aplica al " onload
". En este caso, es común que el código "externo" haga poco, simplemente configura la solicitud y luego la envía. En este caso, la sobrecarga adicional de una función adicional como en el código anterior es innecesaria. Su retrieve_rate debería parecerse más a esto:-
retrieve_rate : function()
{
var self = this;
var ajax = new XMLHttpRequest();
ajax.open('GET', 'http://xyz.example', true);
ajax.onreadystatechanged= function()
{
if (ajax.readyState == 4 && ajax.status == 200)
{
// prefs available as self.prefs
}
}
ajax.send(null);
}
El comportamiento predeterminado de setInterval
es vincularse al contexto global. Puede llamar a una función miembro guardando una copia del contexto actual. Dentro de retrieve_rate la this
variable estará correctamente vinculada al contexto original. Así es como se vería su código:
var self = this;
this.intervalID = setInterval(
function() { self.retrieve_rate(); },
this.INTERVAL);
Consejo adicional: para una referencia de función simple (a diferencia de una referencia de objeto que tiene una función miembro), puede cambiar el contexto utilizando métodos call
o de JavaScript apply
.