不同时间循环的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"> </div>
我正在创建一个加载条,并在 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
})
});
你可以尝试重新安排你的代码逻辑来做这样的事情。如果在此期间我找到更好的解决方案,我会编辑答案。
编辑:这个
编辑 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"> </div>