本文来自 @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任务队列末尾。

转载于:https://www.cnblogs.com/chenrf/p/10106433.html

前端读者 | 由setTimeout引发的JS引擎运行机制的研究相关推荐

  1. Vue.js 内部运行机制之总结 常见问题解答

    Vue.js 内部运行机制之总结 & 常见问题解答 总结 在本小册的第一节中,笔者对 Vue.js 内部运行机制做了一个全局的概览,当时通过下面这张图把 Vue.js 拆分成一个一个小模块来介 ...

  2. JS9day(BOM对象模型,setTimeout定时器,JS单线程执行机制,location对象,swiper插件,localStorage本地存储,购物车案例升级版,学习信息案例(本地存储))

    文章目录 BOM简介 定时器-延时函数 5秒关闭广告案例 递归模拟setInterval函数 两种定时器对比 JS 执行机制 location对象 navigator对象 histroy对象(了解) ...

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

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

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

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

  5. web前端培训JS 运行机制的梳理

    展现形式:由于是属于系统梳理型,就没有由浅入深了,而是从头到尾的梳理知识体系, 重点是将关键节点的知识点串联起来,而不是仅仅剖析某一部分知识. 内容是:从浏览器进程,再到浏览器内核运行,再到JS引擎单 ...

  6. js中立即执行函数会预编译吗_作为前端你了解JavaScript运行机制吗?

    作为前端工程师,大家都知道js是前端一开始就要学会的知识点,js的代码你会写了,那js的运行机制你了解吗?只有了解了js的运行机制,才能在工作中如鱼得水,今天就跟随珠峰的老师一起来了解下js的运行机制 ...

  7. JS引擎线程的执行过程的三个阶段

    浏览器首先按顺序加载由<script>标签分割的js代码块,加载js代码块完毕后,立刻进入以下三个阶段,然后再按顺序查找下一个代码块,再继续执行以下三个阶段,无论是外部脚本文件(不异步加载 ...

  8. Javascript 引擎工作机制(js层面梳理)

    转载地址:http://www.jb51.net/article/98610.htm 我们需要引入几个相关的概念:执行环境栈.全局对象.执行环境.变量对象.活动对象.作用域和作用域链等,这些概念正是J ...

  9. JS引擎线程的执行过程的三个阶段(二)

    继续 JS引擎线程的执行过程的三个阶段(一) 内容, 如下: 三. 执行阶段 1. 网页的线程 永远只有JS引擎线程在执行JS脚本程序,其他三个线程只负责将满足触发条件的处理函数推进事件队列,等待JS ...

最新文章

  1. lm358数据手册_如何阅读运放的数据手册(1)查找数据手册
  2. 【送书福利8本】YYDS《剑指Offer》,百万程序员人手一册
  3. MySql修改数据库编码为UTF8
  4. .NET 社区 NB,2019 中国 .NET 开发者峰会
  5. 【elasticsearch系列】双击elasticsearch.bat闪退,日志排查报错信息
  6. 后台定时统计任务太耗时如何优化一下
  7. python 标签字体大小_这文档动画,怎么用 Python 实现的?
  8. Python调用C语言函数
  9. 汇编debug与masm命令
  10. 大数据分析平台有哪些主要功能
  11. php 表单验证代码,php 表单验证实现代码
  12. eclipse安装ADT插件
  13. PPT 动画模板使用技巧
  14. HUSTOJ平台的搭建
  15. D3js-中国各主要大城市经纬度数据
  16. 塞雷三分钟漫画中国史1
  17. SCAU------8615 快乐
  18. Spring Boot - 开启 HttpBasic 认证方式
  19. GitHub 的 Pull Request 是指什么意思?
  20. Ansys在高分屏电脑下的显示以及Fluent的图形显示界面黑屏问题

热门文章

  1. 互联网发展趋势:社区化、碎片化、一站式、寒冬
  2. wpf Command Binding
  3. linux监控nmon和analyser的使用
  4. sqlalchemy 外键
  5. HTML5-Canvas 图形变换+状态保存
  6. 网络编程——第一篇 基础之进程线程
  7. jQuery复制节点
  8. PHP 如何准确取得服务器地址IP[非代理]
  9. 报表学习总结(一)——ASP.NET 水晶报表(Crystal Reports)的简单使用
  10. 营销区块链技术的艺术