0

setInterval がループで使用されているという問題に直面しています。URL の配列を入力として受け取る関数 subscribeFeed( ) があります。URL 配列をループし、setInterval 関数を使用して各 URL を getFeedAutomatically() にサブスクライブします。

したがって、配列に 3 つの URL がある場合、3 つの setInterval が呼び出されます。問題は、1) どの setInterval がどの URL に対して呼び出されているかを区別する方法です。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));
}

このようにオンザフライでクロージャーを作成するときは、大量の変数をクロージャー スコープにドラッグしないように注意する必要があります。上記のリンクと以下のコードは、これを安全に行う方法を示しています。

コードの一部を変更して、コピーする必要のないものをコピーしないようにしました。

//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 に答える