博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
前端读者 | 由setTimeout引发的JS引擎运行机制的研究
阅读量:5068 次
发布时间:2019-06-12

本文共 1379 字,大约阅读时间需要 4 分钟。

本文来自 @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

你可能感兴趣的文章
js 读写cookie。不同路径会储存各自的cookie。而 在v.net环境下读写是在 / 根目录。...
查看>>
笔记草稿。
查看>>
Maven配置默认使用的JDK版本
查看>>
课后作业1
查看>>
ActiveMQ_1学习
查看>>
指针做参数的动态内存分配与二重指针(上)
查看>>
UVA - 1602 Lattice Animals (暴力+同构判定)
查看>>
微信小程序点击图片全屏展示,并可以翻下一张图
查看>>
背景图片固定不随页面上下滚动而滚动 ,属性 background-attachment
查看>>
python和anacoda安装第三方库的位置
查看>>
20155335俞昆《java程序设计》第10周总结
查看>>
EMACS::基本操作
查看>>
Css3 文字渐变整理(一)
查看>>
在win系统安装Git
查看>>
nodejs fs路径
查看>>
动态规划算法之最大子段和
查看>>
linux c:关联变量的双for循环
查看>>
深入浅出理解zend framework(三)
查看>>
python语句----->if语句,while语句,for循环
查看>>
javascript之数组操作
查看>>