不同时间循环的setTimeout

setTimeout in loop with different times

我正在创建一个加载条,并在 var barMovement.

中传递不同的毫秒数和样式参数

我的问题是,在 setTimeout 函数中,时间为 100 毫秒的最后一个参数没有最后输出。

当我用控制台记录结果时,结果显示为 100、200、200、100、200、300,但实际上应该是 100、200, 200、200、300、100

如果我没理解错的话,最后一个参数 100 会先输出,因为它更快,但是是否有解决此问题的方法或使 setTimeout 延迟到上一个 setTimeout 循环完成的方法?

谢谢!

function BarSequence(style){
 this.style = style

 this.move = function(styles) {
  var i = 0;

  for(len = styles.length; i < len; i++){

    (function loopy(index) {

        setTimeout(function() {
          console.log(style[index])
        }, i * style[index][0]);
    })(i);

   }
  }
}

var barMovement = new BarSequence([
[100, { width: '10%' }],
[200, { width: '20%' }],
[200, { width: '50%' }],
[200, { width: '80%' }],
[300, { width: '90%' }],
[100, { width: '100%' }]
]);

barMovement.move(barMovement.style);

我相信做这种事情的唯一方法是在彼此内部声明 setTimeouts,例如:

setTimeout(function(){
    //execute the work to be done
    setTimeout(function(){
        //execute the work to be done
        // ... and so on
    })
});

你可以尝试重新安排你的代码逻辑来做这样的事情。如果在此期间我找到更好的解决方案,我会编辑答案。

编辑:这个 很好地解释了如何处理 setTimeouts 执行。

编辑 2:这是一个糟糕的方法,因为删除代码的动态性不是一个好的做法。检查来自 @epascarello

您正在将它乘以指数。所以你的超时是 0、200、400、600、1200、500 所以最后一个会在 400 和 600

之前

为了让它们按顺序加载,您需要将之前的时间附加到它。你应该做的是不要使用超时循环。只需增加一个计数器并遍历数组。

var barMovement = [
  [100, {width: '10%'}],
  [200, {width: '20%'}],
  [200, {width: '50%'}],
  [200, {width: '80%'}],
  [300, {width: '90%'}],
  [100, {width: '100%'}]
];

var cnt = 0;

function run() {
  window.setTimeout(function() {
    document.getElementById("bar").style.width = barMovement[cnt][1].width
    cnt++;
    if (cnt < barMovement.length) run();
  }, barMovement[cnt][0])
}

run()
#bar {
  background-color: green;
  width: 0;
}
<div id="bar">&nbsp;</div>