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();