遍历数组并延迟函数
Looping through an array and delaying a function
我正在尝试连续遍历一个数值数组,这些数值将作为触发另一个函数的延迟值传递给 setInterval 函数。这是我拥有的:
HTML:
<p>On</p>
JavaScript:
$(document).ready(function(){
var timing = [5000, 10000, 17000, 8000, 14000, 9000, 12000, 8000, 20000, 7000, 13000, 7000, 17000, 8000, 13000, 12000, 18000]
//function to change
function change(){
var p = $("p").html();
if(p === "On"){
$("p").html("Off");
} else {
$("p").html("On");
}
}
function myFunction(){
for (var i = 0; i < timing.length; i++){
var switchTime = timing[i];
setInterval(function(){
change();
},switchTime);
}
} myFunction();
});
我想让更改函数在不同的延迟时间连续触发。现在我 运行 的时间似乎不正确。任何建议表示赞赏。谢谢!
只需在 setInterval
函数中增加变量 i
。
function myFunction(){
for (var i = 0; i < timing.length; ){
var switchTime = timing[i];
setInterval(function(){
change();
i++;
},switchTime);
}
}
使用 setTimeout
而不是 setInterval
因为您是在循环中执行此操作。 setInterval
将初始化一个定时器,该定时器在指定的延迟时连续触发(例如,如果延迟 5 秒,它将在 5、10、15 等时触发)。通过在 迭代 中使用 setTimeout
,定时器在指定延迟后每次迭代仅触发一次,下一次迭代为下一个延迟值初始化一个新定时器。
我假设您在调用 setInterval
时可能不会清除旧间隔。根据 https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval,您可能需要使用 clearInterval
清除之前的间隔。特别是如果您对所有时间间隔都使用相同的方法,我认为您可能得不到想要的结果。所以:
- 创建区间,全局保存当前ID
- 当您的回调被调用时,使用
clearInterval
函数清除当前间隔
- 重复
无论如何,使用循环是行不通的,因为很多setInterval
(或setTimeout()
)都是"instantly"在几微秒内启动的。
所以他们按照他们自己的 timing[i]
所说的做他们的工作,但几乎是在同一时间!
相反,您必须在前一个步骤结束时启动每个步骤。
这是一个工作示例(另见 this fiddle),我在其中添加了一些过程的视觉跟踪:
HTML:
<p id="on-off">On</p>
<p id="delay"></p>
Javascript:
$(document).ready(function(){
var timing = [
5000, 10000, 17000, 8000, 14000, 9000, 12000, 8000, 20000, 7000, 13000,
7000, 17000, 8000, 13000, 12000, 18000
];
function myFunction(i){
i |= 0;
if (i < timing.length - 1) {
var switchTime = timing[i]
$onOff = $('#onOff');
$('#delay').html('i=' + i + ', delay=' + switchTime);
$onOff.html($onOff.html() == 'On' ? 'Off' : 'On');
setTimeout(
function() {
myFunction(i + 1);
}, switchTime
)
} else {
$('#delay').html('end');
}
}
myFunction();
});
我正在尝试连续遍历一个数值数组,这些数值将作为触发另一个函数的延迟值传递给 setInterval 函数。这是我拥有的:
HTML:
<p>On</p>
JavaScript:
$(document).ready(function(){
var timing = [5000, 10000, 17000, 8000, 14000, 9000, 12000, 8000, 20000, 7000, 13000, 7000, 17000, 8000, 13000, 12000, 18000]
//function to change
function change(){
var p = $("p").html();
if(p === "On"){
$("p").html("Off");
} else {
$("p").html("On");
}
}
function myFunction(){
for (var i = 0; i < timing.length; i++){
var switchTime = timing[i];
setInterval(function(){
change();
},switchTime);
}
} myFunction();
});
我想让更改函数在不同的延迟时间连续触发。现在我 运行 的时间似乎不正确。任何建议表示赞赏。谢谢!
只需在 setInterval
函数中增加变量 i
。
function myFunction(){
for (var i = 0; i < timing.length; ){
var switchTime = timing[i];
setInterval(function(){
change();
i++;
},switchTime);
}
}
使用 setTimeout
而不是 setInterval
因为您是在循环中执行此操作。 setInterval
将初始化一个定时器,该定时器在指定的延迟时连续触发(例如,如果延迟 5 秒,它将在 5、10、15 等时触发)。通过在 迭代 中使用 setTimeout
,定时器在指定延迟后每次迭代仅触发一次,下一次迭代为下一个延迟值初始化一个新定时器。
我假设您在调用 setInterval
时可能不会清除旧间隔。根据 https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval,您可能需要使用 clearInterval
清除之前的间隔。特别是如果您对所有时间间隔都使用相同的方法,我认为您可能得不到想要的结果。所以:
- 创建区间,全局保存当前ID
- 当您的回调被调用时,使用
clearInterval
函数清除当前间隔 - 重复
无论如何,使用循环是行不通的,因为很多setInterval
(或setTimeout()
)都是"instantly"在几微秒内启动的。
所以他们按照他们自己的 timing[i]
所说的做他们的工作,但几乎是在同一时间!
相反,您必须在前一个步骤结束时启动每个步骤。
这是一个工作示例(另见 this fiddle),我在其中添加了一些过程的视觉跟踪:
HTML:
<p id="on-off">On</p>
<p id="delay"></p>
Javascript:
$(document).ready(function(){
var timing = [
5000, 10000, 17000, 8000, 14000, 9000, 12000, 8000, 20000, 7000, 13000,
7000, 17000, 8000, 13000, 12000, 18000
];
function myFunction(i){
i |= 0;
if (i < timing.length - 1) {
var switchTime = timing[i]
$onOff = $('#onOff');
$('#delay').html('i=' + i + ', delay=' + switchTime);
$onOff.html($onOff.html() == 'On' ? 'Off' : 'On');
setTimeout(
function() {
myFunction(i + 1);
}, switchTime
)
} else {
$('#delay').html('end');
}
}
myFunction();
});