我有这个(片段)我的网站,我需要从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){})
}
答案 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;在不同的范围内工作。