在 javascript 个闭包中使用 setInterval

Using setInterval inside javascript closures

我是 javascript 的新手,目前正在阅读有关闭包的内容。我试图实现一个示例以更好地理解这个概念。

这是片段:

function getValue() {
  let a = 0

  const runner = async () => {
    a += 1
  }

  setInterval(runner, 100)
  
  return () => {
    return a
  }
}

let value = getValue()
console.log(value()) -----> logging statement 1

// some long operation

console.log(value()) -----> logging statement 2

但是,我看到的输出是:

1
1

我希望这两个日志语句输出两个不同的值。我的理解是,一旦 getValue() 被调用,runner 函数就会定期执行。变量 a 将得到更新,因此第二个 console.log 应该打印一个增量值 a

你几乎完成了,只是错过了主要部分。

操作进行得太快了。 运行 第二次迭代不需要 100 毫秒,因此值保持不变。

尝试至少等待 100 毫秒,因为您的间隔需要这段时间来递增。

如下例所示。

function getValue() {
  let a = 0

  const runner = async () => {
    a += 1
  }

  setInterval(runner, 100)
  
  return () => {
    return a
  }
}

let value = getValue()
console.log(value())

// operations are happening too fast

setTimeout(() => console.log(value()), 100);
setTimeout(() => console.log(value()), 200);
setTimeout(() => console.log(value()), 300);

function getValue() {
  let a = 0

  const runner = () => {
    a += 1
    console.log("Runner's A: " +a)
  }

  setInterval(runner, 100)
  
  return () => {
    return a
  }
}

let value = getValue()
console.log(value());// -----> logging statement 1

// some long operation

console.log(value());// -----> logging statement 2

https://jsbin.com/geponejuba/edit?js,console,output

正如上面指出的 js 是单线程的,所以它的工作方式是,你的日志语句首先执行,如果没有别的事可做,那么 setTimeout/setInterval 被执行(这是一个非常简化语句,详细版本可以阅读“事件循环”)

在我分享的示例 jsbin 中,您可以看到正在调用 setInterval 并且确实在更新值。