具有setInterval的多个计时器

时间:2013-11-12 12:58:11

标签: javascript loops timer closures setinterval

我遇到了在循环中使用setInterval的问题。 我有一个函数subscribeFeed(),它接受一个url数组作为输入。 它循环遍历url数组,并使用setInterval函数将每个url订阅到getFeedAutomatically()。

所以如果数组中有三个URL,那么将调用3个setInterval。 问题是 1)如何区分为哪个URL调用哪个setInterval。 2)它导致setInterval中的运行时异常(我猜是因为javascript中的闭包问题)

//constructor
function myfeed(){
    this.feedArray = [];
}

myfeed.prototype.constructor= myfeed;
myfeed.prototype.subscribeFeed =function(feedUrl){
      var i=0;
      var url;
      var count = 0;
      var _this = this;
  var feedInfo = {
                url : [],
        status : ""
    };
      var urlinfo = [];
      feedUrl = (feedUrl instanceof Array) ? feedUrl : [feedUrl];
     //notifyInterval = (notifyInterval instanceof Array) ? notifyInterval: [notifyInterval];

    for (i = 0; i < feedUrl.length; i++) {

        urlinfo[i] = {
                url:'',
                notifyInterval:5000,// Default Notify/Refresh interval for the feed 
                isenable:true,      // true allows the feed to be fetched from the URL
                timerID: null,      //default ID is null
                called : false,
                position : 0,
                getFeedAutomatically : function(url){
                    _this.getFeedUpdate(url);
                },
            };


            urlinfo[i].url  = feedUrl[i].URL;

            //overide the default notify interval 
            if(feedUrl[i].NotifyInterval /*&& (feedUrl[i] !=undefined)*/){
                urlinfo[i].notifyInterval = feedUrl[i].NotifyInterval;  
            }


        // Trigger the Feed registered event with the info about URL and status 
        feedInfo.url[i] = feedUrl[i].URL;  

        //Set the interval to get the feed.
        urlinfo[i].timerID = setInterval(function(){
                             urlinfo[i].getFeedAutomatically(urlinfo[i].url);
                        }, urlinfo[i].notifyInterval);

         this.feedArray.push(urlinfo[i]);

        }
    }
// The getFeedUpate function will make an Ajax request and coninue
  myfeed.prototype.getFeedUpdate = function( ){


  }

我在jsfiddle上发布了同样的内容 http://jsfiddle.net/visibleinvisibly/S37Rj/

提前感谢你

2 个答案:

答案 0 :(得分:0)

经过一些原型设计后,我找到了一个答案,答案就是将关闭移到外面

function myclass(){

}
myclass.prototype.funone= function(){
    var counter =0;
    var timerID;
    timerID = setInterval( function(){
        alert(counter++);
    },1000);

}

myclass.prototype.funtwo= function(){
 var timerID2;
    var counter2 =50;
    timerID2 = setInterval( function(){
        alert(counter2++);
    },2000);    
}

myclass.prototype.funthree = function( ){

    var urlArray =["google.com","yahoo.com"];
    var timeArray =[15000,6000];
    var timerID ;
  for(var i=0;i<2; i++){   
      var url = urlArray[i];
      var timerinterval = timeArray[i];
    timerID =  this.register( url,timerinterval); 
  }       
}
myclass.prototype.register = function(url,timerInterval){

    var myUrl =url;
    var myTimer = timerInterval;
    var timerID  = setInterval( function(){
        alert(myUrl+"with"+ myTimer);
    },myTimer);      

}

var m = new myclass( );
m.funthree( ); 


http://jsfiddle.net/visibleinvisibly/Q4SBG/13/

The move the index binding from the setInterval and pass the url and time interval.
It works perfectly

答案 1 :(得分:0)

您可能需要查看this answer(位于底部的“此变量”下)this值的含义。

代码中的错误可能与在循环中使用计数器并根据计数器创建闭包有关。创建此类闭包的最简单方法是。

for(i=0;i<len;i++){
  object.myCallback = (function(counter){
    return function(){
      doSomethingWith(counter);
    }
  }(i));
}

在动态创建闭包时,应注意不要将大量或大量变量拖入闭包范围。上面的链接和下面的代码显示了如何安全地执行此操作。

我已经改变了一些代码以使其更简单并且不复制不需要复制的东西,setInterval是setTimeout所以它只执行一次,但它是相同的想法。

//constructor
function MyFeed(){
  this.feedArray = [];
}
MyFeed.prototype.subscribeFeed =function(feedUrl){
  var i=0,urlInfo=[];
  feedUrl = (feedUrl instanceof Array) ? feedUrl : [feedUrl];
  for (i = 0; i < feedUrl.length; i++) {
    feedUrl[i].isEnable=true;
    feedUrl[i].called=false;
    feedUrl[i].position=0;//not sure what this is supposed to do
    //Set the interval to get the feed.
    feedUrl[i].timerID = setTimeout(this.closures//changed this to timeout
      .getFeedUpdate(this)
      ,feedUrl[i].notifyInterval||100//changed default value
    );
    this.feedArray.push(feedUrl[i]);
    }
};
// The getFeedUpate function will make an Ajax request and coninue
MyFeed.prototype.getFeedUpdate = function( index ){
  console.log("in getFeedUpdate, this is now:",this);
  console.log("my feed url object:",this.feedArray[index].url);
};
//limit closure scope, define closure creators here
MyFeed.prototype.closures={
  //this.closures.getFeedUpdate(this)
  //  will return a closure that calls this.getFeedUpdate
  //  with correct parameters
  getFeedUpdate:function(me){
    var index = me.feedArray.length;
    return function(){
      me.getFeedUpdate(index);
    };
  }
};

//code to test adding single feed
var mf = new MyFeed();
mf.subscribeFeed({
  url:"I am last",
  notifyInterval:1000
});
//add another single feed
mf.subscribeFeed({
  url:"first.com"
});
//and another
mf.subscribeFeed({
  url:"second.com"
});
//and add some more feeds in an array of feeds
mf.subscribeFeed([
  {
    url:"third"
  },
  {
    url:"fifth"
  },
  {
    url:"no, I am last",
    notifyInterval:1500
  }
]);

使用FireBug插件或Chrome尝试FireFox并按F12查看控制台,当日志语句记录您可以单击它的内容时,可以查看已记录项目的详细信息。记录this之类的对象或index

等简单值非常有用