说到setTimeout写过javascript的伙伴们一定不会陌生,去银行办过存取款业务的伙伴一定对取号机不会陌生。今天群里有个好伙伴在问setTimeout的问题,大伙你一言我一语,讲了很多,可是她听了之后还是不理解。我先不说她的问题,请先回忆一下,去银行或医院排队的时候,是不是要先去机器上取一个号码呀。也不知从几何时,取号机就开始流行起来了。不过这也确实是好事,不用一直站在那里排呀排,而且可以知道前面有多少人排在我前面,因此大可以放心的坐在椅子上刷微博,玩微信。等到叫你手中的号码时,就轮到你了。这个我相信大多数人都玩过,就不细说了。下面我要说的这个问题,或许可以用上面的情景来类比,以帮助理解。当然,比的不好,也可以吐槽。

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

那么问题来了,这个id是干嘛用的,为什么输出了10个4144 ?

首先查了一下w3c,上面对setTimeout是这么解释的:setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。关于它的返回值解释在度娘上很少,或许是我搜的问题,最近google要翻墙才能用了,不爽。我也不管他娘是怎么给它定义的,反正理解成系统分配给它的号码就行了,简单粗暴。这个号码与浏览器当前的运行环境有关。所以你运行上面的代码,不一定是这个数字. 这就好比同一个人去每个银行的取号机上拿到的号码不一定相同是一个道理。

学过计算机原理的人一般都会知道,cpu一次只能做一件事情,它把忙不过来的任务放在缓存区,比如优先级最高的排在一级缓存,次要的排在二级缓存,再次要的放内存,最后是硬盘。总之呢,是要排队一个一个的处理。cpu怕忙乱了,于是呢给每一个任务都排了一个号码,取一个专业点的名字,叫id,这样叫到谁,谁就开始执行。有时候,某些任务会被用户取消。比如岛国片看到一半,女朋友突然回来了,急忙关掉播放器。这时系统就会告诉cpu,播放岛国片的那个id用户取消了,cpu就跳过这个id不做了。 这就和取号机是一样样的,如果你取了号,又临时有事走了。广播叫的那个号码被你拿走了,你又不在。自然就不管你了。关于这个id七七八八就写了这么多,也不知道看官您整明白了没有。

下面接着说那个输出10个4144的问题。其实这个问题是一个老生常谈的问题了,本质上都是异步的问题。

我上面说了,setTimeout用于在指定的毫秒数后做某事,而for循环里边是当前立即开始要做的事。我们的cpu虽然一次只能做一件事,但是它的速度是很快的,一秒钟都可以完成N多件事情(N等于一个很大的数)。上面的代码等价于:

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

所以当第一个setTimeout执行的时候,for循环早就完成了,id的值也就是最后那个setTimeout返回的id。 所以输出10个一样的id值,也就不足为怪了。

如果想要查看每一个setTimeout返回的id是多少,直接这样写就可以了:

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

虽然setTimeout里边的任务是指定时间后执行,但是它的id值是即时返回的,就比如你取号的时候,不管要过久才能轮到你,但是只要你点了取号机,它就会立即打印给你。

这个过程是同步的。当然,关于setTimeout还有很多知识点,也有很多坑,但是只要注意它这里有个异步的问题,大多数情况都可以避免。

本篇是原创,如果对你有帮助,请点击 推荐,如果有什么地方有疑问,欢迎跟贴探讨。

setTimeout与取号机之间的关系的更多相关文章

  1. UNICODE与UTF8和GBK之间的关系

    http://wenku.baidu.com/link?url=bheGEzfSjEx-QX-ciME5oKooKYE08_NJZ02l2kKFa7kVZJ4t8Ks2uSNByovgP2QL6btq ...

  2. struts2(四) ognl表达式、值栈、actionContext之间的关系

    今天来说说ognl表达式在struts2中的运用. --wh 一.什么是Ognl? 通过百度百科查询到的解释,其中详细的说明了OGNL的作用. 下面我们就对OGNL这5个作用进行讲解 1.存取对象的任 ...

  3. 探索未知种族之osg类生物---状态树与渲染树以及节点树之间的关系

    节点树 首先我们来看一个场景构建的实例,并通过它来了解一下“状态节点”StateGraph 和“渲染叶”RenderLeaf 所构成的状态树,“渲染台”RenderStage 和“渲染元”Render ...

  4. Struts2学习(四)———— ognl表达式、值栈、actionContext之间的关系

    一.什么是Ognl? 通过百度百科查询到的解释,其中详细的说明了OGNL的作用. 下面我们就对OGNL这5个作用进行讲解 1.存取对象的任意属性,简单说就是对javabean进行操作(重要) 2.调用 ...

  5. JPA概述以及它和Hibernate之间的关系

    http://www.cnblogs.com/Kevin-ZhangCG/p/8996491.html 一.JPA概述以及它和Hibernate之间的关系 1.1.Hibernate 概述 JPA J ...

  6. 五、hibernate表与表之间的关系(一对多关系)

    数据库表与表之间的关系 一对多:一个学校可以有多个学生,一个学生只能有一个学校 多对多:一个学生可以有多个老师,一个老师可以教多个学生 一对一:一个人只能有一个身份证号,一个身份证号只能找到一个人 一 ...

  7. php CGI、Fastcgi、PHP-FPM的详细介绍与之间的关系

    以下PHP CGI.Fastcgi.PHP-FPM的一些信息归纳和汇总----->详细介绍与之间的关系 一:CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的 web ...

  8. 关于计算机的ID和用户ID之间的关系

    关于计算机的ID和用户ID之间的关系 计算机安装完系统后就会生成计算机ID,然后系统会以计算机ID为前缀附加数字创建Administrator(500)和Guest(501)用户ID,其他用户的ID将 ...

  9. 并发用户数与 TPS 之间的关系

    1.  背景 在做性能测试的时候,很多人都用并发用户数来衡量系统的性能,觉得系统能支撑的并发用户数越多,系统的性能就越好:对TPS不是非常理解,也根本不知道它们之间的关系,因此非常有必要进行解释. 2 ...

随机推荐

  1. 再生核希尔伯特空间(RKHS)在监督学习(SVM)中的应用

    [转载请注明出处]http://www.cnblogs.com/mashiqi 2014/4/10 在网上找到一个讲reproducing kernel的tutorial看了一看,下面介绍一下. 首先 ...

  2. 手写PE文件(二)

    [文章标题]: 纯手工编写的PE可执行程序 [文章作者]: Kinney [作者邮箱]: mohen_ng@sina.cn [下载地址]: 自己搜索下载 [使用工具]: C32 [操作平台]: win ...

  3. 纯js实现DIV拖拽

    写代码的时候遇到需要对绝对布局的div进行拖拽的功能,起初为了省事直接在网上扒拉了一番,看到大神张鑫旭的一篇文章<JavaScript实现最简单的拖拽效果>,便直接拿来使用(膜拜大神).但 ...

  4. Java中使用long类型实现精确的四则运算

    引子 Effective Java 2nd Edition 第48条建议:如果需要精确的答案,请避免使用float和doble.float和double类型主要是为了科学计算和工程计算而设计的.他们执 ...

  5. PMI-ACP练习题知识积累-打印版

    敏捷铁三角的参数:价值,质量,约束.传统的铁三角包括的参数是范围,进度和成本 敏捷计划的三个主要层级为:发布计划,迭代计划,每日计划 敏捷开发模型的特征包括 开发由多个迭代组成. 敏捷拥抱不确定性,而 ...

  6. css小demo

    span{ color: #ccc; float: right; font-weight: bold; display: inline-block; border-right: solid 1px # ...

  7. Drectx 3D窗口后台截图

    //GDI与DX截屏API操作 LPDIRECTDRAW lpDD = NULL; LPDIRECTDRAWSURFACE lpDDSPrime = NULL; LPDIRECTDRAWSURFACE ...

  8. Python - 更改pip源至国内镜像

    永久使用 [windows] 在用户名目录下创建一个目录 C:\Users\xxx\pip [linux] ~/.pip/pip.conf 新建pip.ini [global] index-url = ...

  9. Spark源码分析 &ndash; SparkEnv

    SparkEnv在两个地方会被创建, 由于SparkEnv中包含了很多重要的模块, 比如BlockManager, 所以SparkEnv很重要 Driver端, 在SparkContext初始化的时候 ...

  10. vscode新版1.31.1使用代码检查工具ESlint支持VUE

    1.VSCODE中安装ESlint省略 2.菜单文件->首选项->设置->扩展->ESLint 打钩:Eslint:Auto Fix On Save 点击此链接:在settin ...