在for循环中运行setTimeout是前端开发很常见的一种模式。最近被考了一道相关的题目觉得很有意思也很容易犯错,于是记录下来当做学习笔记。
下面先来看一段代码:

  for(var i=0;i<10;i++){setTimeout(console.log(i),0);}

看完这段代码思考一下结果输出是什么呢?
是不是第一时间想到的是连续的10个10呢?啊哈哈这样就错啦~
答案是0、1、2、3、4、5、6、7、8、9哦,这是因为很多人把这段代码与下面的代码混淆了

for(var i=0;i<10;i++){setTimeout(function(){console.log(i);  //连续的10个10},0);}

这段代码输出结果是连续的10个10。
首先我们来说一下为什么是连续的10个10。因为在for循环中使用setTimeout涉及到了异步机制。说到异步机制那就要说一下JS的运行机制。
JS是单线程环境,也就是说代码的执行是从上到下,依次执行。也就是同一个时间只能做一件事。

单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。JavaScript将所有任务分成两种,一种是同步任务,另一种是异步任务。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

在所有同步任务执行完之前,任何的异步任务是不会执行的。 而setTimeout就是一个异步任务,所以会先执行for循环这个同步任务,把setTimeout()放进任务队列中等待主线程的for循环执行完毕,一旦"执行栈"中的所有同步任务执行完毕(循环结束后此时i=10)就会从队列中取出setTimeout()
for循环一次碰到一个 setTimeout(),并不是马上把setTimeout()拿到异步队列中,而要等到一秒后,才将其放到任务队列里面。

异步执行的运行机制如下:
所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
主线程不断重复上面的第三步。
主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会循环反复。

一般来说,有以下四种会放入异步任务队列:

  1. setTimeout和setlnterval
  2. DOM事件
  3. ES6中的Promise
  4. Ajax异步请求

回归正题,既然在for循环中运行setTimeout()涉及到了异步,那上面的解释不就解决问题了吗,可是为什么第一段代码结果不是连续的10个10呢?这就涉及到了console.log 与console.log()的区别了。
看下面代码:

看懂了吗,看懂了这道题也就解决了啊哈哈
其实console.log 与console.log()的区别就是 console.log()是立即执行的也就是IIFE,而console.log只是一个function 函数名。所以console.log()是同步任务跟for循环是同步执行的,而setTimeout()是异步任务需要等到主线程的同步任务执行完毕后才能执行,所以结果就是0、1、2、3、4、5、6、7、8、9了。

再来看一段代码:

 for(var i=0;i<10;i++){setTimeout("console.log(i)",1000);//连续的10个10}

啊哈哈,这时候结果就是连续的10个10了。

原因在于加了双引号的console.log()不再是立即执行函数。setTimeout() 会判断第一个参数是否是[function],如果不是,则会尝试将它当做字符串处理。也就是说,console.log(i)执行后的返回值转为字符串。

现在明白在for循环中运行setTimeout()的三种情况区别了吧

 for(var i=0;i<10;i++){setTimeout(console.log(i),0);//0、1、2、3、4、5、6、7、8、9}for(var i=0;i<10;i++){setTimeout(function(){console.log(i);//连续的10个10},0);}for(var i=0;i<10;i++){setTimeout("console.log(i)",1000);//连续的10个10}

参考文章
https://blog.csdn.net/Febby_/article/details/89513819
异步知识参考来源:
https://baijiahao.baidu.com/s?id=1615713540466951098&wfr=spider&for=pc

js setTimeout的三种情况相关推荐

  1. 在for循环中运行setTimeout的三种情况

    在for循环中运行setTimeout是前端开发很常见的一种模式.最近被考了一道相关的题目觉得很有意思也很容易犯错,于是记录下来当做学习笔记. 下面先来看一段代码: for(var i=0;i< ...

  2. ES6中let的用法及一个小案例,在for循环中运行setTimeout的四种情况:

    1.ES6中let和var的主要区别: (1)let声明的变量只在当前块级作用域内有效. if(true){var a=1;let b=2; } console.log(a); console.log ...

  3. 【重复提交表单】表单重复提交的三种情况,解决办法

    引入 看一个重复提交表单的例子 F12可以看到,请求体中的参数在刷新页面之后仍然保留,因此每一次刷新页面,都会把现有的请求体中的表单数据提交一次到服务器,而接收的页面还是insert.jsp,于是造成 ...

  4. java基础:map遍历使用;java使用 Patten 和Matches 进行正则匹配;后端传到前端展示图片三种情况,并保存到手机;

    文章目录 前言 一.map 遍历方法 二.java正则学习 三.后端传到前端图片三种情况 1. 图片流数据(InputStream) 转 base64,前端展示保存 a. 后端:输入流转base,直接 ...

  5. 对象的notify方法的含义和对象锁释放的三种情况

    1,notify的含义     (1)notify一次只随机通知一个线程进行唤醒 (2)在执行了notify方法之后,当前线程不会马上释放该对象锁,呈wait状态的线程也不能马上获得该对象锁, 要等到 ...

  6. SSO单点登录三种情况的实现方式详解

    SSO单点登录三种情况的实现方式详解 单点登录(SSO--Single Sign On)对于我们来说已经不陌生了.对于大型系统来说使用单点登录可以减少用户很多的麻烦.就拿百度来说吧,百度下面有很多的子 ...

  7. 野指针出现的三种情况

    昨天面试被问到"你了解野指针吗",我的回答是"野指针就是没有初始化的指针,这样的指针会随机指向一块内存,野指针会对系统造成破坏(造成内存泄漏)".面试官又问到, ...

  8. mysql002多表查询.on链接分为三种情况,左链接,右链接,全链接

    -- on链接(最实用),分为三种情况,左链接,右链接,全链接 -- 左外链接,左表全部显示,如果匹配不到右表的内容使用null代替. SELECT * FROM emp e LEFT JOIN de ...

  9. shiro单点登录原理_SSO单点登录三种情况的实现方式详解

    单点登录(SSO--Single Sign On)对于我们来说已经不陌生了.对于大型系统来说使用单点登录可以减少用户很多的麻烦.就拿百度来说吧,百度下面有很多的子系统--百度经验.百度知道.百度文库等 ...

最新文章

  1. 二叉树的四种遍历方式(递归和非递归双重实现)
  2. Java多线程之单例模式在多线程环境下的安全问题
  3. Mybatis之加载mybatis-config.xml
  4. 微信可以远程控制电脑吗_用微信就能远程控制电脑,这款神器有些厉害
  5. ORACLE JOB 失败 查看,Oracle JOB异常中断原因分析
  6. Python求解进制问题(阿里巴巴2015笔试题)
  7. 关于含光 800,这里有你想要的一切答案!
  8. shell脚本不换行刷新数据
  9. mysql 配置root密码_Mysql安装与配置调优及修改root密码的方法
  10. 21. Django进阶:内建用户系统
  11. 20个开发人员非常有用的Java功能代码(一)
  12. json标准格式举例_JSON 数据格式详解
  13. spark的数三角形算法_腾讯开源全栈机器学习平台 Angel 3.0,支持三大类型图计算算法...
  14. 学术界AV1编码优化技术的进展
  15. Python常用配置文件ini、json、yaml读写总结
  16. 1099:零起点学算法06——再来一题除法算术题
  17. 【学习笔记】常见测试类型测试方法
  18. 软件工程应用与实践(1)——项目简介和小组分工
  19. 基于微信小程序的校园二手交易
  20. 搭建个人的Leanote云笔记本

热门文章

  1. 16个魅力男人(上)
  2. 小程序苹果6s兼容遇到的坑的总结
  3. 【爬虫】第七部分 scrapy
  4. 惠普286Pro G2 MT电脑怎么用win10pe安装系统
  5. 关于Python中Inf与Nan的判断问题详解
  6. deepin安装xfce4
  7. Ubuntu22.10 安装微信方法
  8. 人工智能概率第一次作业
  9. 基于51单片机带温湿度显示的可调电子时钟
  10. idea配置javap命令