对setTimeout函数的理解
之前去面试一家公司时,面试官出了一道关于js的setTimeout函数的题目:
/*
*面试官给的原题目如下:
*执行mytest()后,控制台输出内容是_____
*function mytest() {
* for(var i = 0; i < 5; i ++)
* setTimeout(console.log(i),0);
*}
*但这应该不是面试官的问题,当时我也没有发现问题,回来测试后才发现,这个函数不是
*面试官要表达的意思。
*/
//正确的代码如下:
function mytest() {
for(var i = 0; i < 5; i ++)
setTimeout(function(){
console.log(i);
},0);
}
我的回答是:控制台输出为5 5 5 5 5,虽然答案对了,但是解释就太牵强了,我说是因为for语句之执行速度比setTimeout函数快,面试笑了笑,呜呜~~(这有毛关系)。
后来网上找了一些资料,参考了一些书籍,这里我给出一个靠谱的解释:
首先,我们必须承认,js是单线程的,即使是对于ajax异步方式或者像setTimeout这样的函数。
其次,我们要理解js函数的执行过程,对于setTimeout这样的函数来说并不是每次都能按照预定延迟的时间执行指定函数的。下面举一个列子:
比如有一个函数fun0在执行开始时创建了一个定时器T1,T1定时器将在200ms后被触发指定函数。这时我们需要考虑一个问题,假设fun0的执行时间为250ms(大于200ms),那将会怎样?前面已经说过,js是单线程的,所以不存在fun0和定时器同时执行的情况。这时候定时器制定的函数会在fun0执行完后才执行,定时器的等待时间为250ms,并不是我们指定的200ms。
对于javascript这样的执行方式,我们可以想象在函数执行过程中有两个队列。队列Q1是指执行队列,每次只能执行一个函数;队列Q2就是等待队列,存放着将要执行的函数。每当有一个函数要执行时,就会先把这个函数放进等待队列,如果Q1为空,那么久立即执行这个函数。当然在大多数情况下,函数都是立即执行的。
因此,我们可以知道,setTimeout定时器指定的函数必须要在当前执行队列为空时才会执行。
现在我们再来分析一下上面那道题,很显然,每次的for循环都触发了一个定时函数,这些定时函数有点特殊,是立即执行的(如果执行队列为空的话)。但是在每次触发时,for循环都还未结束,也就是执行队列不为空,此时新建的定是函数只能放在等待队列里无法立即执行。当最后一次for循环执行结束后,执行队列变为空,这时等待队列的函数就立即进入到了执行队列,于是就开始执行只控制台输出。因为setTimeout指定的匿名函数中i的值是一种引用值(自行谷歌脑补),所以输出结果为5 5 5 5 5。
如描述或理解有误,欢迎各位留言!!
对setTimeout函数的理解的更多相关文章
- JavaScript callback function 回调函数的理解
来源于:http://mao.li/javascript/javascript-callback-function/ 看到segmentfault上的这个问题 JavaScript 回调函数怎么理解, ...
- js setTimeout函数
最近在看JS DOM编程艺术,在第十章的动画里面有个setTimeout函数的例子中涉及了很多的引号,研究了好大一会才看明白,综合网上各个大神的解释和自己的理解,其原理是这样的: 首先看下程序源代码: ...
- opengl中对glOrtho()函数的理解
glOrtho是创建一个正交平行的视景体. 一般用于物体不会因为离屏幕的远近而产生大小的变换的情况.比如,常用的工程中的制图等.需要比较精确的显示. 而作为它的对立情况, glFrustum则产生一个 ...
- 什么是setTimeout函数和setInterval函数?
我们一般在浏览网页的时候,一般都会有图片轮播等,一些比较好玩的特效,接下来我就给大家讲讲这俩个函数! 一setTimeout函数和setInterval函数的语法以及应用 1.setTimeout函数 ...
- 回调函数透彻理解Java
http://blog.csdn.net/allen_zhao_2012/article/details/8056665 回调函数透彻理解Java 标签: classjavastringinterfa ...
- 对c语言中malloc和free函数的理解
最近在复习c语言的时候再次用到了malloc函数和free函数,此处着讲解一下自己对这两个函数的理解和认识. 一. malloc函数和free函数的基本概念和基本的用法 对于malloc函数: 1. ...
- js中的回调函数的理解和使用方法
js中的回调函数的理解和使用方法 一. 回调函数的作用 js代码会至上而下一条线执行下去,但是有时候我们需要等到一个操作结束之后再进行下一个操作,这时候就需要用到回调函数. 二. 回调函数的解释 因为 ...
- 浅谈setTimeout函数和setInterval函数
前几天学了js,看到了两个非常有趣的函数,他们分别是setTimeout函数和setInterval函数,这两个函数能使网页呈现非常一些网页中比较常见的效果,比如说图片轮播,等一些非常好玩的效果.下面 ...
- JS匿名函数的理解
js匿名函数的代码如下:(function(){ // 这里忽略jQuery 所有实现 })(); 半年前初次接触jQuery 的时候,我也像其他人一样很兴奋地想看看源码是什么样的.然而,在看到源码的 ...
随机推荐
- phpStudy:使用localhost无法访问的解决方案
今天遇到新的问题,很有意思,当使用Localhost时,发现报403错误: 百度找到问题所在:没有权限问题 所以我们打开phpStudy,找到配置文件“vhosts-conf”,看到的情况是这样的 接 ...
- OpenGL学习 Introduction
OpenGL and Graphics Pipeline The word pipeline is from production lines in factories.Generating a pr ...
- EF问题集合
1. 在使用数据迁移的过程中,如果手工删除了本地数据库之后,再次尝试连接被删除的数据库,会有以下提示: System.Data.SqlClient.SqlException (0x80131904): ...
- java对象传递小解析
先上代码: import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder ...
- C# is运算符
一.C# is运算符 is运算符用于检查对象是否与给定类型兼容(兼容表示对象是该类型,或者派生于该类型). is运算符用来检查对象(变量)是否属于某种数据类型,如int.string.bool.dou ...
- JS中的var、let、const
1.var 在全局window中申明则为全局变量,是全局对象 window 的属性. var sum = 0 console.log(window.sum) console.log(sum); 在函数 ...
- element el-tooltip 内容换行的方法
<el-tooltip class="item" effect="light" placement="top-start"> ...
- 我是如何根据豆瓣api来理解Restful API设计的
1.什么是REST REST全称是Representational State Transfer,表述状态转移的意思.它是在Roy Fielding博士论文首次提出.REST本身没有创造新的技术.组件 ...
- Git工作流指南:功能分支工作流(转)
一旦你玩转了集中式工作流,在开发过程中可以很简单地加上功能分支,用来鼓励开发者之间协作和简化交流. 功能分支工作流背后的核心思路是所有的功能开发应该在一个专门的分支,而不是在master分支上.这个隔 ...
- (排班表二)后台动态绘制Grid表格
后台动态绘制值班表(Grid表格 列名不固定) 要求:表头除了值班人姓名,还要显示日期,及每天的星期值,用斜杠‘/’分隔.即:几号/星期几 最终实现的效果:根据查询的年月显示每个值班人查询月份每天的值 ...