用于循环功能

时间:2015-05-14 14:48:03

标签: javascript function api loops

我有这个(片段)我的网站,我需要从TVDB / MovieDB API中获取数据。我需要一集的截图,所以我使用

theMovieDb.tvEpisodes.getImages({
"id": showID,
"season_number": season_number,
"episode_number": episode_number
}, function(data){}, function(error){})

我需要执行6次,因为我需要6个图像和6个不同的剧集。

for(var i = 0; i < 7; i++){

}

但问题是,如果我现在在console.log(i)部分内询问function(data){},则会记录6六次......
我做错了什么?

这是完整的代码,其他函数的变量等...

      for(var i = 0; i < 6; i++) {
    iF = i;
    u = i + 1
    epLen = data.episodes[data.episodes.length - 1 - i]
  var thies = "<center><span style='font-family: Arial'>" + epLen.season_number + 'x' + epLen.episode_number + ": <br>" + epLen.name + "<br>"+ epLen.air_date +"</span></center>";
  var thisId = "recent" + u.toString();
  var text = thies;
  document.getElementById(thisId).innerHTML = text;
  theMovieDb.tvEpisodes.getImages({"id": showID, "season_number": epLen.season_number, "episode_number": epLen.episode_number},
  function(data){
    var data = JSON.parse(data);
    window.still = data.stills[0].file_path;
    console.log(window.still);
    console.log(iF); // logs 5
    console.log(i); // logs 6
},
  function(error){})
  //alert(i)

  //var still = window.still;
  //console.log(still);
  //var epStil = "https://image.tmdb.org/t/p/original" + still.stills[0].file_path;
  //var epStill = "url(" + epStil + ")";
  //document.getElementsByClassName("recent")[i].style.backgroundImage = epStill;

}

修改
我找到了解决方案,因为它被标记为重复,我不能再回答了,所以我会在这里发布:

epStilArray = [];
  for(var i = 0; i < 6; i++) {
    iF = i;
    u = i + 1
    epLen = data.episodes[data.episodes.length - 1 - i]
  var thies = "<center><span style='font-family: Arial'>" + epLen.season_number + 'x' + epLen.episode_number + ": <br>" + epLen.name + "<br>"+ epLen.air_date +"</span></center>";
  var thisId = "recent" + u.toString();
  var text = thies;
  document.getElementById(thisId).innerHTML = text;
  theMovieDb.tvEpisodes.getImages({"id": showID, "season_number": epLen.season_number, "episode_number": epLen.episode_number},
  function(data){
    var data = JSON.parse(data);
    still = data.stills[0].file_path;
    var epStil = "https://image.tmdb.org/t/p/original" + still;
    var epStil = "url(" + epStil + ")";
    epStilArray.push(epStil);
    console.log(epStilArray);
    document.getElementsByClassName("recent")[epStilArray.length - 1].style.backgroundImage = epStil;
},
  function(error){})
}

3 个答案:

答案 0 :(得分:1)

你有一个关闭问题。有许多资源可以了解有关js中闭包的更多信息。 Here is the JSLint entry on it specific to loops.

您可以通过创建IIFE并传入计数器副本来修复它。

for(var i = 0; i < 6; i++) {
    (function (iCopy) {
        iF = iCopy;
        u = iCopy + 1
        epLen = data.episodes[data.episodes.length - 1 - iCopy]
        var thies = "<center><span style='font-family: Arial'>" + epLen.season_number + 'x' + epLen.episode_number + ": <br>" + epLen.name + "<br>"+ epLen.air_date +"</span></center>";
        var thisId = "recent" + u.toString();
        var text = thies;
        document.getElementById(thisId).innerHTML = text;
        theMovieDb.tvEpisodes.getImages({"id": showID, "season_number": epLen.season_number, "episode_number": epLen.episode_number},
            function(data){
                var data = JSON.parse(data);
                window.still = data.stills[0].file_path;
                console.log(window.still);
                console.log(iF); // logs 5
                console.log(iCopy); // logs 6
            },
            function(error){})
    }(i));
}

答案 1 :(得分:1)

这是一个很好的例子,您可以使用JavaScript闭包来确保内联函数的每个实例都可以访问i的不同值。

这样做的一种方法是将代码包装在一个立即调用的函数表达式(IIFE)中,并在与该函数表达式范围相关的另一个变量中捕获所需变量的副本。这可以采用(function(){ var iCopy = i; /*your code here*/})();(function(iCopy){ /*your code here*/})(i);

的格式完成

在IIFE中将复制的变量设置在自己的行中:

for(var i = 0; i < 6; i++) {
    ...
    (function(){
        var iCopy = i; // i is copied to iCopy
        theMovieDb.tvEpisodes.getImages({},
            function(data){
                ...
                console.log(iCopy); 
            }, function(error){});
    })(); // this IIFE has its own scope capturing a copy of the variable i
 }

或者,将变量作为参数传递给IIFE:

for(var i = 0; i < 6; i++) {
    ...
    (function(iCopy){ // i is copied to iCopy
        theMovieDb.tvEpisodes.getImages({},
            function(data){
                ...
                console.log(iCopy); 
            }, function(error){});
    })(i); // this IIFE has its own scope capturing a copy of the variable i as a parameter
}

另请注意,您不必更改复制变量的名称;为了清楚起见,我只在上面的例子中这样做了。如果不同作用域中的两个变量共享相同的名称,则代码将引用更直接(最内部)的作用域。因此,以下代码也可以工作:

for(var i = 0; i < 6; i++) {
    ...
    (function(i){ // i is copied to i
        theMovieDb.tvEpisodes.getImages({},
            function(data){
                ...
                console.log(i); 
            }, function(error){});
    })(i); // this IIFE has its own scope capturing a copy of the variable i as a parameter
}

答案 2 :(得分:0)

为了解决问题,我只是将函数调用放在循环中,并且运行正常。这个问题确实可能与异步工作流和闭包有关,所以如果订单很重要,只需传递变量&#34; i&#34;在关闭。

例如,下一个代码日志: i = 0.i = 1.i = 2.i = 3.i = 4.i = 5

function myFunction(f) {f()}

for (var i = 0; i < 6; i++) {
    myFunction(function() { console.log('i = ' + i); })
}

同样在你的问题中,我发现你使用&#34; var i&#34;和&#34; iF&#34; w / o&#34; var&#34;在不同的范围内工作。