Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript setInterval和'this'解决方案_Javascript_This_Setinterval - Fatal编程技术网

Javascript setInterval和'this'解决方案

Javascript setInterval和'this'解决方案,javascript,this,setinterval,Javascript,This,Setinterval,我需要从我的setInterval处理程序访问此 prefs: null, startup : function() { // init prefs ... this.retrieve_rate(); this.intervalID = setInterval(this.retrieve_rate, this.INTERVAL); }, retrieve_rate : function() {

我需要从我的
setInterval
处理程序访问

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.com', true);
        ajax.onload = function()
        {
            // access prefs here
        }
    }

如何在
ajax.onload
中访问此.prefs?

这不是美容解决方案,但它是常用的:

var self = this;
var ajax = null;
//...
ajax.onload = function() {
    self.prefs....;
}

setInterval行应如下所示:-

 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.
 ); 
retrieve_rate : function()
{
    var self = this;
    var ajax = new XMLHttpRequest();
    ajax.open('GET', 'http://xyz.com', true);
    ajax.onreadystatechanged= function()
    {
        if (ajax.readyState == 4 && ajax.status == 200)
        {
            // prefs available as self.prefs
        }
    }
    ajax.send(null);
}
编辑:相同的原则适用于“
onload
”。在这种情况下,“外部”代码通常很少做什么,它只是设置请求,然后发送请求。在这种情况下,上述代码中附加函数的额外开销是不必要的。您的检索率应该如下所示:-

 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.
 ); 
retrieve_rate : function()
{
    var self = this;
    var ajax = new XMLHttpRequest();
    ajax.open('GET', 'http://xyz.com', true);
    ajax.onreadystatechanged= function()
    {
        if (ajax.readyState == 4 && ajax.status == 200)
        {
            // prefs available as self.prefs
        }
    }
    ajax.send(null);
}

setInterval
的默认行为是绑定到全局上下文。您可以通过保存当前上下文的副本来调用成员函数。在retrieve_rate内,
变量将正确绑定到原始上下文。下面是您的代码的外观:

var self = this;
this.intervalID = setInterval(
    function() { self.retrieve_rate(); },
    this.INTERVAL);

额外提示:对于普通函数引用(与具有成员函数的对象引用相反),您可以使用JavaScript的
调用
应用
方法更改上下文。

这将是最干净的解决方案,由于大多数情况下,您实际上希望为连续的方法调用切换此上下文:

this.intervalID = setInterval(this.retrieve_rate.bind(this), this.INTERVAL);
此外,更容易掌握的概念

    // store scope reference for our delegating method
    var that = this;
    setInterval(function() {
        // this would be changed here because of method scope, 
        // but we still have a reference to that
        OURMETHODNAME.call(that);
    }, 200);

随着浏览器支持的改进,现在可以很好地使用,以正确地保留

startup : function()
    {
        // init prefs
        ...
        this.retrieve_rate();
        this.intervalID = setInterval( () => this.retrieve_rate(), this.INTERVAL);
    },
当间隔调用
retrieve\u rate()
时,使用=>方法保留
。不需要在parameters.setInterval(function(){console.log(this)}.bind(this),100)中使用funky self或传递
this


这在javascript中是合法的,可以保存大量代码:)

在现代浏览器中,setInterval方法允许在计时器过期后将附加参数传递给func指定的函数

因此,一个可能的解决方案可以是:

this.intervalID = setInterval(function (self) {
        self.retrieve_rate();
    }, this.INTERVAL, this);
演示:

var-timerId;
document.querySelector(“#clickMe”).addEventListener('click',函数(e){
timerId=setInterval(函数(自身){
self.textContent=self.textContent.slice(0,-1);
if(self.textContent.length==0){
清除间隔(timerId);
self.textContent='end..';
}
},250,这个);
})


单击我
在传递给
setInterval
的函数中,将引用全局对象。你是说
context.retrieve\u rate
而不是
this.retrieve\u rate
?这是朝着正确的方向发展的,不需要将上下文作为参数传递。@Matthew,Anthony那么我如何从onload访问它呢?尝试了这个.prefs,但没有成功…不客气,Matthew,顺便说一下,您不需要使用
调用
上下文。检索率()
就足够了,因为您有一个基本对象(
上下文。
),再次感谢@Anthony和@CMS.)当闭包起作用时,很容易变得不必要的“聪明”。问题是
setInterval
如何调用
retrieve\u rate
函数,方法中的
这个
值指的是全局对象…我本来打算这样做的,但后来我想起了这种模式对循环非常有用。@Matthew Flaschen:它对这种情况和循环一样有用。@Anthony:所以使用
self
的技巧是这里唯一的选择?你能确认Matthew的解决方案不起作用吗?@Michael:首先,这不是一个“把戏”,而是Javascript的工作方式。马修在写这篇评论时的回答是无效的。有一个早期版本的它可能已经工作了,但它涉及将
this
作为一个参数传递,这是不必要的,而且是awkard(任何
retrieve\u rate
的调用方都会知道这个不必要的特殊要求)。将
this
作为参数传递给
(函数(self){…})(this)
在setInterval中对我不起作用,因为函数是立即执行的,而不是延迟执行的@Joel Fillmore的解决方案对meThis有效。这对我有效,但似乎不需要调用“call”。默认情况下,retrieve_rate的上下文应设置为self,因为它是作为成员函数调用的。@Dreendle-你说得对,我记得在需要回调函数引用时解决了这个问题。我已经确定了答案,谢谢!这是正确的解决方案。公认的解决方案似乎需要不必要的更多代码,但这种方法有一个缺点。最有可能的是,它将无法与旧版本的IE@Nechehin值得注意。但它仍然是一个更干净的解决方案。它是受支持的,因为IE9对我来说是一个干净的解决方案。如果您需要对IE8的支持,并且正在使用,您可以使用:
this.intervalID=setInterval(u.bind(this.retrieve\u rate,this),this.INTERVAL)