前端读者 | 由setTimeout引发的JS引擎运行机制的研究
本文来自 @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);
}
这里主要的问题在:
- 闭包的概念
- 也是最终要的,关于
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引擎运行机制的研究的更多相关文章
- 试着讲清楚:js代码运行机制
一. js运行机制 js执行引擎 经常看文章的说到js是带线程的,其实这个说法非常的模糊,准确的是js执行引擎是单线程的,js执行引擎就是js代码的执行器,有了这个概念就可以下来说说js是如何运行的了 ...
- JS的运行机制
代码块: JS中的代码块是指由<script>标签分割的代码段.JS是按照代码块来进行编译和执行的,代码块间相互独立(即就算代码块1出错,但不影响代码块2的加载和执行),但变量和方法共享. ...
- 关于js内部运行机制的一本好书
读<单页Web应用一书>,第二章讲了js内部运行机制,感觉棒极了.之前读<你不知道的js>,看的云里雾里,似懂非懂.没想到单页Web一书将此内容讲的如此通俗易懂,好多困惑已久的 ...
- 深入理解 JS 引擎执行机制(同步执行、异步执行以及同步中的异步执行)
首先明确两点: 1.JS 执行机制是单线程. 2.JS的Event loop是JS的执行机制,深入了解Event loop,就等于深入了解JS引擎的执行. 单线程执行带来什么问题? 在JS执行中都是单 ...
- JS 引擎执行机制
JS JS 是单线程语音 JS 的 Event Loop 是 JS 的执行机制.类似于 Android Handler 消息分发机制 JS 单线程 技术的出现都跟现实世界里的应用场景密切相关 JS 单 ...
- 从Event Loop谈JS的运行机制
这里主要是结合Event Loop来谈JS代码是如何运行的. 事件循环对于我们平时开发可以说是特别重要,可以让我们写出更好的代码. 到这里相信我们已经知道了JS引擎是单线程,而且这里会用到前面说的的几 ...
- 《JavaScript总结》js的运行机制
首先大家都知道javascript是单线程语言. 什么是单线程呢?比如我们去车站买票,只有一个售票窗口,大家排队买票,需要前面的人买完票,后面的人才能买票. 那为什么javascript不能是多线程呢 ...
- cocos2d-x C++ 原始工程引擎运行机制解析
新建一个工程,相信感兴趣的同学都想知道cocos引擎都是如何运行的 想知道是如何运行的,看懂四个文件即可 话不多说,上代码: 1.首先解释 AppDelegate.h #ifndef _APP_DEL ...
- JS中==运行机制
1. 判断两边是否有NaN,如果有则一律返回false 2.判断两边是否含有布尔值,如果有的话则将true转化为1,false转化为0. 3.遇到null或者undefined,则不会进行类型转换,它 ...
随机推荐
- ringbuffer
http://blog.csdn.net/xiaolang85/article/details/38419163
- oracle to_char格式数值
C:\Users\XXX>sqlplus / as sysdba SQL :: Copyright (c) , , Oracle. All Rights Reserved. 连接到: Oracl ...
- AngularJs学习——常用表单指令练习
一.知识点 ng-show.ng-hide.ng-if(控制元素显示隐藏,区别在于ng-hide是是否显示隐藏元素,而ng-if是是否移除元素): ng-src.ng-class(为元素添加路径和cl ...
- Spring Security 集成CAS实现单点登录
参考:http://elim.iteye.com/blog/2270446 众所周知,Cas是对单点登录的一种实现.本文假设读者已经了解了Cas的原理及其使用,这些内容在本文将不会讨论.Cas有Ser ...
- 洛谷P2868 [USACO07DEC]观光奶牛 Sightseeing Cows
题目描述 Farmer John has decided to reward his cows for their hard work by taking them on a tour of the ...
- Spring mvc详解(山东数漫江湖)
Spring mvc框架 Spring web MVC 框架提供了模型-视图-控制的体系结构和可以用来开发灵活.松散耦合的 web 应用程序的组件.MVC 模式导致了应用程序的不同方面(输入逻辑.业务 ...
- HDU 1422 重温世界杯 (dp)
题目链接 Problem Description 世界杯结束了,意大利人连本带利的收回了法国人6年前欠他们的债,捧起了大力神杯,成就了4星意大利. 世界杯虽然结束了,但是这界世界杯给我们还是留下许多值 ...
- bzoj 2669 状压DP
因为最多有8个'X',所以我们可以用w[i][s]来表示现在我们填了前i个数,填的X的为S,因为每次新加进来的数都不影响前面的最小值,所以我们可以随便添加,这样就有了剩下所有位置的方案,每次都这样转移 ...
- SpringCloud Feign重试详解
摘要: 今天在生产环境发生了数据库进程卡死的现象,除了sql因为全量更新,没加索引的原因,最主要还是我们的接口的服务器端接口出现问题了.忽视了更新接口的幂等性,以及调用方feign client的重试 ...
- 9.0docker的数据管理
dopcker容器的数据卷 为容器添加数据卷 sudo docker run -v ~/container data:/data -it ubuntu /bin/bash 查 ...