0

我正面临在循环中使用 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/上发布相同的内容

提前谢谢你

4

2 回答 2

0

您可能想看看这个答案(在底部的“这个变量”下)关于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

于 2013-11-13T15:51:45.267 回答
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
于 2013-11-13T07:59:42.750 回答