js setTimeout运行机制
在开始之前先看个面试例子
为什么会是0 1 2 2,而不是 0 0 1 1
再来看个例子

输出结果是4个undefined,为何不是1,2,3,4?
这是为什么呢,这是因为setTimeout是异步的,运行机制是指定的代码,必须等到本次执行的所有同步代码都执行完,才会执行。优先关系:异步任务要挂起,先执行同步任务,同步任务执行完毕才会响应异步任务。
这里解释下异步执行过程,浏览器有个定时器(timer)模块,定时器到了执行时间才会把异步任务放到异步队列,for循环体执行的过程中并没有把setTimeout放到异步队列中,只是交给定时器模块了。4个循环体执行速度非常快(不到1毫秒)。定时器(即使设置了0默认也是4毫秒)到了设置的时间才会把setTimeout语句放到异步队列中。
看张图:

先来说说第一个例子:for循环结束时候此时j = 2,浏览器定时器模块中的setTimeout交给了任务队列后输出,所以就有了0=》1=》2=》2
再来说说第二个例子:也是同样的道理,messages执行了四次,然后for循环结束,此时i=4,因为messages[4]没有值为undefined,最大为3,所有是4个undefined
最后说说例二解决方法
方法一:

使用let,不要用var,因为let是有作用域的,所以setTimeout的i值指向的是每个循环体中的i值,每次循环的值都是不一样的,打印出来的是最终输出1,2,3,4
方法二(闭包):

这个就很好理解了,因为每个i的值都会传入function中,setTimeout中的i作用域在这个闭包中,每次指向的是闭包中的i,所以打印出来的值1,2,3,4
总结:setTimeout是异步函数,异步任务要挂起,先执行同步任务,同步任务执行完毕才会响应异步任务
js setTimeout运行机制的更多相关文章
- JS的运行机制
代码块: JS中的代码块是指由<script>标签分割的代码段.JS是按照代码块来进行编译和执行的,代码块间相互独立(即就算代码块1出错,但不影响代码块2的加载和执行),但变量和方法共享. ...
- 试着讲清楚:js代码运行机制
一. js运行机制 js执行引擎 经常看文章的说到js是带线程的,其实这个说法非常的模糊,准确的是js执行引擎是单线程的,js执行引擎就是js代码的执行器,有了这个概念就可以下来说说js是如何运行的了 ...
- 关于js内部运行机制的一本好书
读<单页Web应用一书>,第二章讲了js内部运行机制,感觉棒极了.之前读<你不知道的js>,看的云里雾里,似懂非懂.没想到单页Web一书将此内容讲的如此通俗易懂,好多困惑已久的 ...
- 《JavaScript总结》js的运行机制
首先大家都知道javascript是单线程语言. 什么是单线程呢?比如我们去车站买票,只有一个售票窗口,大家排队买票,需要前面的人买完票,后面的人才能买票. 那为什么javascript不能是多线程呢 ...
- 前端读者 | 由setTimeout引发的JS引擎运行机制的研究
本文来自 @xiaoyuze88 链接:http://xiaoyuze88.github.io/ 太久没碰代码了,那天想到关于循环调用setTimeout实现每隔一秒输出递增的数的那个问题,搞了搞,发 ...
- 从Event Loop谈JS的运行机制
这里主要是结合Event Loop来谈JS代码是如何运行的. 事件循环对于我们平时开发可以说是特别重要,可以让我们写出更好的代码. 到这里相信我们已经知道了JS引擎是单线程,而且这里会用到前面说的的几 ...
- setTimeout运行机制简要理解
经典例子辅助理解setTimeout工作原理 运行结果: 约1秒后输出:1,再过约1秒后输出:2,接着才立即输出:时间流逝了: 2002 毫秒最后输出:时间又流逝了: 2003 毫秒 在现有浏览器环境 ...
- 剖析 Vue.js 内部运行机制 (1)
1. new Vue() 之后. Vue 会调用 _init 函数进行初始化,也就是这里的 init 过程,它会初始化生命周 期.事件. props. methods. data. computed ...
- JS中==运行机制
1. 判断两边是否有NaN,如果有则一律返回false 2.判断两边是否含有布尔值,如果有的话则将true转化为1,false转化为0. 3.遇到null或者undefined,则不会进行类型转换,它 ...
随机推荐
- 大厂是怎么进行SQL调优的?
有情怀,有干货,微信搜索[三太子敖丙]关注这个不一样的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文章. ...
- 认识Javascript中的作用域和作用域链
作用域 只要写过java或者c#等语言的同学来说,相信一定能理解作用域的概念,在作用域的范围中,我们可以使用这个作用域的变量,对这个变量进行各种操作.可是,当使用Javascript的时候,相信很多的 ...
- 了解TypeScript
TypeScript :是 JavaScript 的一个超集,支持 ECMAScript 6 标准 1.TypeScript 和 JavaScript的区别?TypeScript 是 JavaScri ...
- 《.NET 5.0 背锅案》第5集-案情大转弯:都是我们的错,让 .NET 5.0 背锅
第1集:验证 .NET 5.0 正式版 docker 镜像问题 第2集:码中的小窟窿,背后的大坑,发现重要嫌犯 EnyimMemcachedCore 第3集-剧情反转:EnyimMemcachedCo ...
- MySQL时间类型datetime、bigint及timestamp的查询效率
前期数据准备 通过程序往数据库插入 50w 数据 数据表: CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `time_dat ...
- 如何通过iptables代理访问内网
场景 A机器能够联通内网机器,B机器能够联通A机器,但是访问不到内网机器,场景是希望通过A机器能够转发直接联通局域网内的其它机器 机器IP 内网为172.0.0.x/24 A机器为172.0.0.10 ...
- Codeforces375D Tree and Queries
dsu on tree 题目链接 点我跳转 题目大意 给定一棵 \(n\) 个节点的树,根节点为 \(1\).每个节点上有一个颜色 \(c_i\) \(m\) 次询问. 每次询问给出 \(u\) \( ...
- 在家看电影音效太差?Boom 3D帮你轻松升级
新片上映后,很多人都会选择去电影院观看,一是为了第一时间看到电影,还有一个原因就是电影院的音效往往可以让人身临其境,更好地感受电影的氛围.那如果在家刷片我们该怎么办呢? 我们可以使用Boom 3D这款 ...
- Java中的主线程
目录 概览 主线程 怎么来控制主线程 主线程和main()函数的关系 主线程中的死锁(单个线程) 概览 前段时间有同事提到了主线程这个名词,但当时我们说的主线程是指Java Web程序中每一个请求进来 ...
- miniconda安装及使用
conda环境配置 安装conda [清华源下载地址](https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/) 官网或百度云网盘下载对应版本 ...