JS中的setTimeout
setTimeout in JS
function x() {
for (let i = 1; i <= 5; i++) {
setTimeout(function() {
console.log(i);
}, i * 1000);
}
console.log("Hello World!!");
}
x();
上述函数产生输出 1 到 5,但产生每个输出需要 1 秒。这就是我没有得到的......为什么每个都需要 1 秒,为什么 i 的第一个值不是 1 秒,然后 i 的第二个值是 2 秒,依此类推,因为我将毫秒乘以我值?
如果您想要每次添加 i
秒的行为,请执行以下操作:
function x(i, max = Infinity) {
if (i > max) return
console.log("Hello World!! %s", i);
setTimeout(function() {
console.log(i);
x(i + 1, max)
}, i * 1000);
}
x(1, 5);
您遇到的主要困惑很常见,是因为您使用的是循环。计时器回调之外的所有内容都是 JavaScript 正在同步执行,没有延迟。当您 运行 代码 时,循环立即执行 5 次,因此定时器回调函数的 5 个实例在几毫秒内被放置在事件队列中,正是从那个时间点开始,所有5 个计时器回调被延迟,而不是一个回调从前一个回调的完成延迟。
回调的第一个实例在达到初始延迟(1 秒)后 运行s,然后是第二个实例在延迟 运行s 后(2 秒,仅 1秒比第一个函数调用 运行) 晚,然后是第三个 运行s(只比前一个 2 秒晚 1 秒)等等。
您需要做的是将回调的第一个实例放在事件队列中,在它之前有 1 秒的延迟 运行s 然后,当第一个实例完成时,将另一个实例放入事件队列,延迟 2 秒,依此类推。
为此,忘记循环并使计时器函数递归,这实际上会导致重复代码调用,就像循环一样。
let delay = 1000;
let timer = null; // Will hold a reference to the timer
function x() {
timer = setTimeout(function(){
console.log(delay / 1000);
delay += 1000;
if(delay > 5000){
clearTimeout(timer); // Cancel the timer
console.log("Operation Complete!");
} else {
// Because the next call for the parent function comes from within
// the timer callback function, it is delayed until the end of that
// callback function's execution.
x();
}
}, delay);
}
x();
function x() {
for (let i = 1; i <= 5; i++) {
setTimeout(function() {
console.log(i);
}, i * 1000);
}
console.log("Hello World!!");
}
x();
上述函数产生输出 1 到 5,但产生每个输出需要 1 秒。这就是我没有得到的......为什么每个都需要 1 秒,为什么 i 的第一个值不是 1 秒,然后 i 的第二个值是 2 秒,依此类推,因为我将毫秒乘以我值?
如果您想要每次添加 i
秒的行为,请执行以下操作:
function x(i, max = Infinity) {
if (i > max) return
console.log("Hello World!! %s", i);
setTimeout(function() {
console.log(i);
x(i + 1, max)
}, i * 1000);
}
x(1, 5);
您遇到的主要困惑很常见,是因为您使用的是循环。计时器回调之外的所有内容都是 JavaScript 正在同步执行,没有延迟。当您 运行 代码 时,循环立即执行 5 次,因此定时器回调函数的 5 个实例在几毫秒内被放置在事件队列中,正是从那个时间点开始,所有5 个计时器回调被延迟,而不是一个回调从前一个回调的完成延迟。
回调的第一个实例在达到初始延迟(1 秒)后 运行s,然后是第二个实例在延迟 运行s 后(2 秒,仅 1秒比第一个函数调用 运行) 晚,然后是第三个 运行s(只比前一个 2 秒晚 1 秒)等等。
您需要做的是将回调的第一个实例放在事件队列中,在它之前有 1 秒的延迟 运行s 然后,当第一个实例完成时,将另一个实例放入事件队列,延迟 2 秒,依此类推。
为此,忘记循环并使计时器函数递归,这实际上会导致重复代码调用,就像循环一样。
let delay = 1000;
let timer = null; // Will hold a reference to the timer
function x() {
timer = setTimeout(function(){
console.log(delay / 1000);
delay += 1000;
if(delay > 5000){
clearTimeout(timer); // Cancel the timer
console.log("Operation Complete!");
} else {
// Because the next call for the parent function comes from within
// the timer callback function, it is delayed until the end of that
// callback function's execution.
x();
}
}, delay);
}
x();