本文来自 @xiaoyuze88 链接:http://xiaoyuze88.github.io/

太久没碰代码了,那天想到关于循环调用setTimeout实现每隔一秒输出递增的数的那个问题,搞了搞,发现很多概念模糊了,在此总结下。

所谓的循环调用setTimeout实现递增输出,就是说用for循环10次,每隔一秒输出一个从0~9的数。

不多说,直接上最终代码再说,细节后面再谈。

for (var i = 0; i < 10; i++) {
//这里用闭包,为每一个i生成一个独立的上下文环境,传递给里面的console.log,而不会受到setTimeout延时而影响
(function (i) {
`setTimeout`(function () {
console.log(i);
}, 1000 * i)
})(i);
}

这里主要的问题在:

  1. 闭包的概念
  2. 也是最终要的,关于setTimeout等函数的工作机制。

首先闭包,这里就不多说了,在这里,闭包的作用就是给闭包内的函数生成一个不受外面环境干扰的上下文环境,由于js的作用域问题。

如果这里不用闭包,写成诸如:

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

会发现,每隔一秒钟,输出一个10。

这是由于这一个for循环的执行,瞬间就完成了,也就是说,瞬间注册了10个延时执行的函数,每一个隔一秒钟执行。

当注册的时间点到来,开始执行setTimeout中的语句,由于定义域的问题,此时console.log(i)的这个i指向的是已经到达10的for循环中的i,这就是为什么要用闭包来给setTimeout设置独立的上下文环境,而避免需要访问i时访问到了外面的变量。

另外,如果细想一下,会发现setTimeout的工作过程多少让人有点迷惑,到底setTimeout等延时类函数在浏览器中是如何运作的?这就牵扯到下一个问题,关于浏览器中是如果运作的问题。

浏览器中,JS引擎是单线程的,假设一个浏览器中有三个常驻线程,既JS引擎线程、渲染线程、事件触发线程,还有处理完即结束的线程如AJAX异步请求。

其中,JS线程与渲染线程是互斥的,这是为了避免JS控制DOM时与页面渲染发生冲突。而对于JS线程,它是由事件驱动的,由于单线程,所有任务依队列排序。如果页面上触发了事件,如onclick=function(){}、或者由setTimeout添加了一个函数、ajax请求返回的事件等,所有新添加的任务位于队尾等待处理。

由于是单线程,如果线程被阻塞,如while(true){}死循环,则一切新添加的任务都将被阻塞。

由上面所述,就可以理解为什么setTimeout或setInterval设置的延时事件并不是真是函数处理的延时时间,既setTimout(code,1000)并不是一定会在1秒后处理,这段代码发生的仅仅是在1秒后,将待处理函数排与js任务队列末尾。

前端读者 | 由setTimeout引发的JS引擎运行机制的研究的更多相关文章

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

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

  2. JS的运行机制

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

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

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

  4. 深入理解 JS 引擎执行机制(同步执行、异步执行以及同步中的异步执行)

    首先明确两点: 1.JS 执行机制是单线程. 2.JS的Event loop是JS的执行机制,深入了解Event loop,就等于深入了解JS引擎的执行. 单线程执行带来什么问题? 在JS执行中都是单 ...

  5. JS 引擎执行机制

    JS JS 是单线程语音 JS 的 Event Loop 是 JS 的执行机制.类似于 Android Handler 消息分发机制 JS 单线程 技术的出现都跟现实世界里的应用场景密切相关 JS 单 ...

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

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

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

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

  8. cocos2d-x C++ 原始工程引擎运行机制解析

    新建一个工程,相信感兴趣的同学都想知道cocos引擎都是如何运行的 想知道是如何运行的,看懂四个文件即可 话不多说,上代码: 1.首先解释 AppDelegate.h #ifndef _APP_DEL ...

  9. JS中==运行机制

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

随机推荐

  1. ACE中TCP通信

    转载于:http://www.cnblogs.com/TianFang/archive/2006/12/07/585095.html 概述: 传输控制协议TCP(Transmission Contro ...

  2. BZOJ1880: [Sdoi2009]Elaxia的路线(最短路)

    1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 2049  Solved: 805 题目链接:https ...

  3. Trades FZU - 2281 (大数+贪心)

    This is a very easy problem. ACMeow loves GTX1920. Now he has m RMB, but no GTX1920s. In the next n ...

  4. JS学习之函数的属性和方法

  5. 最大公倍数_Greatest Common Divisor

    计算最大公倍数 Static int gcd( int a, int b) { int t; while( b>0) { t = b; b = a % b; a = t; } return a; ...

  6. ? 初识Webx 3

    初识webx 2: http://www.cnblogs.com/lddbupt/p/5552351.html Webx Turbine建立在Webx Framework的基础上,实现了页面渲染.布局 ...

  7. 【BZOJ】1607: [Usaco2008 Dec]Patting Heads 轻拍牛头

    [算法]模拟 #include<cstdio> #include<algorithm> using namespace std; ,maxm=; int a[maxn],A[m ...

  8. NGINX: 反向代理 Nexus

    Nginx 反向代理 nexus 的服务, 一直卡在 Initialize... 解决方式是添加一个 header X-Forwarded-Proto: proxy_set_header X-Forw ...

  9. sass_sass安装

    你会不会因为有些事遇到各种各样的问题而搁置,直到把这个事情被耽误了几天.最近一直在弄sass这个东西,安装的过程中各种问题.sass是一个基于ruby环境开发的,安装sass之前得先把ruby给安装了 ...

  10. arm---先搞清楚各种版本号【转】

    转自:http://blog.csdn.net/linnoo/article/details/53214689 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] ARM的几种版本 ...