setTimeout()跳转到数组的最后一个元素我怎么能阻止这个?

问题描述 投票:0回答:1

我正在尝试在js上构建一个非常简单的交互式电影播放器​​,只是为了好玩。 wireTo(x)按照自己的持续时间触发每个场景,该持续时间在相同的索引上预定义。 (这是我的期望)

我创建了一个循环并将setTimeout函数放在其中。它在每个持续时间属性上迭代没有问题,但它无法处理名称属性(跳转到最后一个)。

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);

我的逻辑有什么问题。任何帮助将非常感激。谢谢。

javascript arrays
1个回答
0
投票

因为vars的范围是函数,所以你只有一个name变量,你在循环中的每次迭代都会使用它。所以你继续覆盖变量,当计时器最终消失时,它们都会看到你用它覆盖的最后一个值。

最简单的解决方法是使用let而不是var。设为块而不是函数,所以每次通过for循环,你都会有一个带有自己绑定的新变量。

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

  setTimeout(function() {
     alert(name); 
  }, parts[x].duration * x);
}
© www.soinside.com 2019 - 2024. All rights reserved.