循环 setTimeout 函数
Looping through setTimeout function
我正在尝试编写一个函数,通过 x 步(本例中的第 1 步、第 2 步)循环 x 次(本例中为 3 次)x 秒(本例中,第 1 步需要 2 秒,第 2 步需要 1 秒)。
所以我希望它循环如下:
第 1 步(2 秒)
第 2 步(1 秒)
第 1 步(2 秒)
第 2 步(1 秒)
第 1 步(2 秒)
第 2 步(1 秒)
我有下面的代码,但它只迭代了一次循环,我不明白为什么。
jQuery('input').click(function () {
for(i = 0; i < 3; i++){
jQuery('div').html('Step 1');
setTimeout(function() {
jQuery('div').html('Step 2');
},2000);
setTimeout(function() {
jQuery('div').empty();
},2000 + 1000);
}
});
我希望循环以相同的时间继续,但在到达 .empty();
后回到开头。
JSFiddle:http://jsfiddle.net/kmyjhgvd/
循环迭代 3 次,但超时始终相同:2000 和 3000,因此您创建了 3 个相同的回调,将在 2 秒内执行,另外 3 个回调将在 3 秒内调用。这里有你想要的,有 6 种不同的超时:
http://jsfiddle.net/nsg7ny7L/1/
jQuery('input').click(function () {
var time=0;
for(i = 0; i < 3; i++){
setTimeout(function() {
jQuery('div').html('Step 1');
},time++*1000);
setTimeout(function() {
jQuery('div').html('Step 2');
},time++*1000);
}
setTimeout(function() {
jQuery('div').empty();
},time++*1000);
});
PS:确保你理解它是如何工作的:JS是单线程的,所以for循环连续调用setTimeout
6次......所有的开始时间几乎相同其中
现在您在没有超时的情况下直接在循环中执行第 1 步,因此第 1 步的所有三个事件将立即发生。然后你在超时中有第 2 步,但所有这三个都有相同的时间延迟,所以它们将在两秒后同时发生。你在不同的时间得到这个:
0: Step 1 (i = 0)
0: Step 1 (i = 1)
0: Step 1 (i = 2)
2000: Step 2 (i = 0)
2000: Step 2 (i = 1)
2000: Step 2 (i = 2)
3000: empty (i = 0)
3000: empty (i = 1)
3000: empty (i = 2)
你会想要这个:
0: Step 1 (i = 0)
2000: Step 2 (i = 0)
3000: Step 1 (i = 1)
5000: Step 2 (i = 1)
6000: Step 1 (i = 2)
8000: Step 2 (i = 2)
9000: empty
将第 1 步和第 2 步设置为超时,并设置时间延迟,使它们在彼此之后发生,即使用 i * 3000
作为偏移量。然后你可以在最后一步之后的单独超时中清空元素:
jQuery('input').click(function () {
for(i = 0; i < 3; i++){
setTimeout(function() {
jQuery('div').html('Step 1');
}, i * 3000);
setTimeout(function() {
jQuery('div').html('Step 2');
}, i * 3000 + 2000);
}
setTimeout(function() {
jQuery('div').empty();
}, 6000 + 3000);
});
递归方法答案:
function recursiveSteps(config) {
var _step = config.step;
config.step++;
jQuery('div').html('Step 1');
setTimeout(function() {
jQuery('div').html('Step 2');
},2000);
setTimeout(function() {
jQuery('div').empty();
},3000);
if(config.step < 3) setTimeout(function() {recursiveSteps(config);}, config.step*1000);
//you could put an "end" step here if needed
}
jQuery('input').click(recursiveSteps);
我没有尝试过代码,但我认为这应该可行
jQuery('input').click(function () {
loopAction (3, 1, 2); // x is number of loops - s1, s2 in seconds
});
function loopAction(x, s1, s2){
If (x>0){ // as long as x>0 start the iteration
jQuery('div').html('Step 1');
setTimeout(function() {
jQuery('div').html('Step 2');
setTimeout(function() {
loopAction(x-1, s1, s2); // recursive call to self
}, s2*1000);
},s1*1000);
} else {
jQuery('div').empty(); // x>0 is false
}
}
jQuery('input').click(function () {
var times = 0,
printStep1 = function(){
JQuery('div').html('Step 1');
setTimeout( printStep2, 1000 );
},
printStep2 = function(){
JQuery('div').html('Step 2');
if( times++ < 3 ) setTimeout( printStep1, 1000 );
};
printStep1();
});
没有JQuery:
document.querySelector('input').addEventListener( "click", function () {
var times = 0,
printStep1 = function(){
document.querySelector('div').innerHTML = 'Step 1';
setTimeout( printStep2, 1000 );
},
printStep2 = function(){
document.querySelector('div').innerHTML = 'Step 2';
if( times++ < 3 ) setTimeout( printStep1, 1000 );
};
printStep1();
});
用超时连续执行一系列步骤的通用方法:
var steps = [
{
timeout: 2000,
action: function() { jQuery('div').html('Step 1'); },
},
{
timeout: 1000,
action: function() { jQuery('div').html('Step 2'); },
},
{
timeout: 1000,
action: function() { jQuery('div').empty(); },
}
];
function executeSteps(times, index) {
index = index || 0;
var task = steps[index];
if(index > 0 || times > 0) {
if(index == 0) times--;
task.action();
setTimeout(function() {
executeSteps(times, (index + 1) % steps.length);
}, task.timeout);
}
}
jQuery('input').click(function () {
executeSteps(3);
});
JSFiddle
我正在尝试编写一个函数,通过 x 步(本例中的第 1 步、第 2 步)循环 x 次(本例中为 3 次)x 秒(本例中,第 1 步需要 2 秒,第 2 步需要 1 秒)。
所以我希望它循环如下:
第 1 步(2 秒) 第 2 步(1 秒) 第 1 步(2 秒) 第 2 步(1 秒) 第 1 步(2 秒) 第 2 步(1 秒)
我有下面的代码,但它只迭代了一次循环,我不明白为什么。
jQuery('input').click(function () {
for(i = 0; i < 3; i++){
jQuery('div').html('Step 1');
setTimeout(function() {
jQuery('div').html('Step 2');
},2000);
setTimeout(function() {
jQuery('div').empty();
},2000 + 1000);
}
});
我希望循环以相同的时间继续,但在到达 .empty();
后回到开头。
JSFiddle:http://jsfiddle.net/kmyjhgvd/
循环迭代 3 次,但超时始终相同:2000 和 3000,因此您创建了 3 个相同的回调,将在 2 秒内执行,另外 3 个回调将在 3 秒内调用。这里有你想要的,有 6 种不同的超时:
http://jsfiddle.net/nsg7ny7L/1/
jQuery('input').click(function () {
var time=0;
for(i = 0; i < 3; i++){
setTimeout(function() {
jQuery('div').html('Step 1');
},time++*1000);
setTimeout(function() {
jQuery('div').html('Step 2');
},time++*1000);
}
setTimeout(function() {
jQuery('div').empty();
},time++*1000);
});
PS:确保你理解它是如何工作的:JS是单线程的,所以for循环连续调用setTimeout
6次......所有的开始时间几乎相同其中
现在您在没有超时的情况下直接在循环中执行第 1 步,因此第 1 步的所有三个事件将立即发生。然后你在超时中有第 2 步,但所有这三个都有相同的时间延迟,所以它们将在两秒后同时发生。你在不同的时间得到这个:
0: Step 1 (i = 0)
0: Step 1 (i = 1)
0: Step 1 (i = 2)
2000: Step 2 (i = 0)
2000: Step 2 (i = 1)
2000: Step 2 (i = 2)
3000: empty (i = 0)
3000: empty (i = 1)
3000: empty (i = 2)
你会想要这个:
0: Step 1 (i = 0)
2000: Step 2 (i = 0)
3000: Step 1 (i = 1)
5000: Step 2 (i = 1)
6000: Step 1 (i = 2)
8000: Step 2 (i = 2)
9000: empty
将第 1 步和第 2 步设置为超时,并设置时间延迟,使它们在彼此之后发生,即使用 i * 3000
作为偏移量。然后你可以在最后一步之后的单独超时中清空元素:
jQuery('input').click(function () {
for(i = 0; i < 3; i++){
setTimeout(function() {
jQuery('div').html('Step 1');
}, i * 3000);
setTimeout(function() {
jQuery('div').html('Step 2');
}, i * 3000 + 2000);
}
setTimeout(function() {
jQuery('div').empty();
}, 6000 + 3000);
});
递归方法答案:
function recursiveSteps(config) {
var _step = config.step;
config.step++;
jQuery('div').html('Step 1');
setTimeout(function() {
jQuery('div').html('Step 2');
},2000);
setTimeout(function() {
jQuery('div').empty();
},3000);
if(config.step < 3) setTimeout(function() {recursiveSteps(config);}, config.step*1000);
//you could put an "end" step here if needed
}
jQuery('input').click(recursiveSteps);
我没有尝试过代码,但我认为这应该可行
jQuery('input').click(function () {
loopAction (3, 1, 2); // x is number of loops - s1, s2 in seconds
});
function loopAction(x, s1, s2){
If (x>0){ // as long as x>0 start the iteration
jQuery('div').html('Step 1');
setTimeout(function() {
jQuery('div').html('Step 2');
setTimeout(function() {
loopAction(x-1, s1, s2); // recursive call to self
}, s2*1000);
},s1*1000);
} else {
jQuery('div').empty(); // x>0 is false
}
}
jQuery('input').click(function () {
var times = 0,
printStep1 = function(){
JQuery('div').html('Step 1');
setTimeout( printStep2, 1000 );
},
printStep2 = function(){
JQuery('div').html('Step 2');
if( times++ < 3 ) setTimeout( printStep1, 1000 );
};
printStep1();
});
没有JQuery:
document.querySelector('input').addEventListener( "click", function () {
var times = 0,
printStep1 = function(){
document.querySelector('div').innerHTML = 'Step 1';
setTimeout( printStep2, 1000 );
},
printStep2 = function(){
document.querySelector('div').innerHTML = 'Step 2';
if( times++ < 3 ) setTimeout( printStep1, 1000 );
};
printStep1();
});
用超时连续执行一系列步骤的通用方法:
var steps = [
{
timeout: 2000,
action: function() { jQuery('div').html('Step 1'); },
},
{
timeout: 1000,
action: function() { jQuery('div').html('Step 2'); },
},
{
timeout: 1000,
action: function() { jQuery('div').empty(); },
}
];
function executeSteps(times, index) {
index = index || 0;
var task = steps[index];
if(index > 0 || times > 0) {
if(index == 0) times--;
task.action();
setTimeout(function() {
executeSteps(times, (index + 1) % steps.length);
}, task.timeout);
}
}
jQuery('input').click(function () {
executeSteps(3);
});