简体   繁体   English

setTimeout()跳到数组的最后一个元素如何防止这种情况?

[英]setTimeout() jumps to last element of array how can i prevent this?

I'm trying to build a very simple interactive movie player on js just for fun. 我试图在JS上构建一个非常简单的交互式电影播放器​​只是为了好玩。 wireTo(x) triggers every scene by its own duration which predefined on same index. wireTo(x)通过在相同索引上预定义的持续时间触发每个场景。 (This is my expectation) (这是我的期望)

I created a loop and put the setTimeout function inside of it. 我创建了一个循环,并将setTimeout函数放入其中。 It iterates without problem on each duration property, but it couldn't handle with name properties(jumps to the last one). 它在每个duration属性上都没有问题地进行迭代,但是不能使用name属性处理(跳转到最后一个属性)。

 var MoviePlayer = (function() { function MoviePlayer(scenes) { this.setSource(scenes); } MoviePlayer.prototype.setSource = function(_scenes) { this.scenes = _scenes; } MoviePlayer.prototype.wireTo = function(number) { var parts = this.scenes[number].parts; for (var x in parts) { var name = parts[x].name; // I think the problem starts here setTimeout(function() { alert(name); }, parts[x].duration * x); } } return MoviePlayer; }()); // scenes configuration json var scenes = [ { ep: 1, parts: [ { name: "episode 1 p1", duration: 1000 }, { name: "episode 1 p2", duration: 3000 } ], next: 2 }, { ep: 2, parts: [ { name: "episode 2 p1", duration: 1000 }, { name: "episode 2 p2", duration: 1000 } ], next: 3 } ]; // instantiation let player = new MoviePlayer(scenes); player.wireTo(0); 

What's the problem with my logic. 我的逻辑有什么问题。 Any help would be very appreciated. 任何帮助将不胜感激。 Thanks. 谢谢。

Because var s are scoped to the function, you have just a single name variable which you're using for every iteration in the loop. 因为var的作用域是函数,所以您只有一个name变量,该变量用于循环中的每个迭代。 So you keep overwriting the variable, and when the timers eventually go off, they all see the last value you overwrote it with. 因此,您将继续覆盖该变量,并且当计时器最终关闭时,它们都将看到您用其覆盖的最后一个值。

Simplest fix is to just use let instead of var. 最简单的解决方法是只使用let而不是var。 Let is scoped to the block instead of the function, and so each time through the for loop you'll have a new variable with its own binding. let的作用域是块而不是函数,因此每次通过for循环时,您将拥有一个具有自己绑定的新变量。

for (let x in parts) { 
  let name = parts[x].name;

  setTimeout(function() {
     alert(name); 
  }, parts[x].duration * x);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM