在开始之前先看个面试例子

为什么会是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运行机制的更多相关文章

  1. JS的运行机制

    代码块: JS中的代码块是指由<script>标签分割的代码段.JS是按照代码块来进行编译和执行的,代码块间相互独立(即就算代码块1出错,但不影响代码块2的加载和执行),但变量和方法共享. ...

  2. 试着讲清楚:js代码运行机制

    一. js运行机制 js执行引擎 经常看文章的说到js是带线程的,其实这个说法非常的模糊,准确的是js执行引擎是单线程的,js执行引擎就是js代码的执行器,有了这个概念就可以下来说说js是如何运行的了 ...

  3. 关于js内部运行机制的一本好书

    读<单页Web应用一书>,第二章讲了js内部运行机制,感觉棒极了.之前读<你不知道的js>,看的云里雾里,似懂非懂.没想到单页Web一书将此内容讲的如此通俗易懂,好多困惑已久的 ...

  4. 《JavaScript总结》js的运行机制

    首先大家都知道javascript是单线程语言. 什么是单线程呢?比如我们去车站买票,只有一个售票窗口,大家排队买票,需要前面的人买完票,后面的人才能买票. 那为什么javascript不能是多线程呢 ...

  5. 前端读者 | 由setTimeout引发的JS引擎运行机制的研究

    本文来自 @xiaoyuze88 链接:http://xiaoyuze88.github.io/ 太久没碰代码了,那天想到关于循环调用setTimeout实现每隔一秒输出递增的数的那个问题,搞了搞,发 ...

  6. 从Event Loop谈JS的运行机制

    这里主要是结合Event Loop来谈JS代码是如何运行的. 事件循环对于我们平时开发可以说是特别重要,可以让我们写出更好的代码. 到这里相信我们已经知道了JS引擎是单线程,而且这里会用到前面说的的几 ...

  7. setTimeout运行机制简要理解

    经典例子辅助理解setTimeout工作原理 运行结果: 约1秒后输出:1,再过约1秒后输出:2,接着才立即输出:时间流逝了: 2002 毫秒最后输出:时间又流逝了: 2003 毫秒 在现有浏览器环境 ...

  8. 剖析 Vue.js 内部运行机制 (1)

    1. new Vue() 之后. Vue 会调用 _init 函数进行初始化,也就是这里的 init 过程,它会初始化生命周 期.事件. props. methods. data. computed ...

  9. JS中==运行机制

    1. 判断两边是否有NaN,如果有则一律返回false 2.判断两边是否含有布尔值,如果有的话则将true转化为1,false转化为0. 3.遇到null或者undefined,则不会进行类型转换,它 ...

随机推荐

  1. 1、线性DP 354. 俄罗斯套娃信封问题

    354. 俄罗斯套娃信封问题 https://leetcode-cn.com/problems/russian-doll-envelopes/ 算法分析 首先我们从两种情况来讨论这个问题: w无重复值 ...

  2. 线程与更新UI,消除偏见,细谈原理

    前言 相信不少读者都阅读过相类似的文章了,但是我还是想完整的把这之间的关系梳理清楚,细节聊好,希望你也能从中学到一些. 进入正题,大家应该都听过这样一句话--"UI更新要在主线程,子线程更新 ...

  3. BRT快速公交系统的可视化实践

    前言 随着城市进程的加快,中国城市机动车的数量飞速增长,造成城市交通拥堵问题越来越严重,城市居民对于改善出行条件的需求尤其是公共交通的便捷性问题也越来越迫切.而BRT(快速公交系统)作为一种新型的客运 ...

  4. webug第十二关:我系统密码忘记了!

    第十二关:我系统密码忘记了! 文件上传 直接上传php一句话, 菜刀链接

  5. selenium元素定位不到问题分析及解决办法

    最近正在学习写自动化测试脚本,遇到一个错误迟迟未解决,导致自信心大受挫败,甚至想放弃. 思考许久突然想到,我遇到的问题是否也有人会遇到,如果有的话问题就应该有解决办法了.没什么问题是百度解决不了的,如 ...

  6. Eclipse中自动生成局部变量

    方法调用后,返回值自动赋值到一个新的局部变量中: (1)鼠标放到方法上,点击Ctrl+1 (2)选择 :Assign statement to new local variable(将语句赋给新的局部 ...

  7. mq网络请求命令设计&消息的批量发送

    RemotingCommand: flag倒数第一位表示请求类型,0请求1返回.倒数第二位1.表示oneway 单条消息发送时,消息体的内容将保存在body种,批量消息发送,需要将多条消息体的内容存储 ...

  8. [BUGCASE]CI框架的post方法对url做了防xss攻击的处理引发的文件编码错误

    一.问题描述 出现问题的链接: http://adm.apply.wechat.com/admin/index.php/order/detail?country=others&st=1& ...

  9. 败家玩意儿!Redis 竟然浪费了这么多内存!

    作为内存数据库,内存空间大小对于 Redis 来说是至关重要的.内存越多,意味着存储的数据也会越多.但是不知道你有没有遇到过这样的情况,明明空间很大,但是内存的使用却不是很理想. 为什么会出现这样的情 ...

  10. 浅谈代理模式与java中的动态代理

    代理模式的定义: 代理模式是一个使用律非常高的模式,定义如下: 为其他对象提供一种代理,以控制对这个对象的访问. 类图: 简单的静态代理: public interface IRunner{ //这是 ...