循环里的定时器如何保存当前循环的值

var value = 0
      while(value++ < 100){
        setTimeout(() => console.log(value),100)
      }

想要结果是1到100,请问怎么改写?谢谢


小疑问:
下面这种实现

var value = 0
while(value++ < 100){
    setTimeout((val => console.log(val))(value),100)
}

为什么会在最后的100之后打出一个大值呢?

阅读 3.3k
4 个回答

需要分配新的内存,不然每次console.log都是输出同一块内存,自然是同一个值。

var value = 0;
while (value++ < 100) {
    (function (v) {
        setTimeout(() => console.log(v), 100);
    })(value)
}
let value = 0;
while(value++ < 100){
    let thisValue = value;
    setTimeout(() => console.log(thisValue),100);
}

楼上的大哥已经给了各种改写。就说下这段代码为什么输出100个101,以及为什么打印出一个“大值”吧

var value = 0
      while(value++ < 100){
        setTimeout(() => console.log(value),100)
      }
      

1.首先要理解,setTimeout是异步的,会被放到任务队列中,直到主进程里的同步代码执行完毕,才会去任务队列执行setTimeout

2.所以setTimeout并不一定是在100毫秒后执行console.log(value),必须有一个前提,就是主进程的同步代码执行完毕,也就是主进程空闲的情况下,100毫秒后执行console.log(value)

3.再回看代码的执行顺序,就是0 < 100所以进去,JS看到setTimeout是异步的,它就把里面的函数扔到任务队列中,然后1 < 100继续进入循环,JS看到还是setTimeout..就继续扔进到任务队列里,扔了100次,终于跳出循环

4.跳出循环之后,主进程也就都执行完了,这时候JS去看任务队列里有100个函数,全是打印console.log(value)的,此时value是101,所以就输出100次101

至于,为什么输出了一个“大值”,你肯定是在开发者工具里运行的,你要是在vscode或者其他编辑器里就没这个问题。开发者工具你每次回车它都会自动返回一个执行结果的.

比如,你输入 var a = 10 回车,它返回undefined,就是说这个语句的执行结果是undefined。

var value = 0
while(value++ < 100){
    setTimeout((val => console.log(val))(value),100)
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题