JavaScript是一门基于对象的弱类型语言,它作为浏览器脚本语言,主要用途是负责与页面的交互,以及操作DOM,它的执行环境是单线程的,默认情况JS是同步加载的,也就是 JS的加载是阻塞的,也就是说同一时间只能完成一件事,只能自上而下执行,万一上一行解析代码的时间很长,那么下面的代码就会被阻塞。对于用户而言,阻塞就意味着"卡死",这样就导致了很差的用户体验。

为了解决这个问题,利用多核CPU的计算能力,于是出现了同步和异步

同步操作,任务遵循队列顺序异步操作,就相当于并线了,因此异步任务不具有阻塞效应。同步任务都是在主线程中执行,形成了一个执行栈,直到主线程空闲时,才会去事件队列中查看是否有可执行的异步任务,如果有就推入主进程中。

JS是通过回调函数实现异步的

一旦用了setTimeout(),里面的回调函数就是异步代码,加入了任务队列,延时调用一个函数不马上执行,而是要等待主队列为空,并达到定的延时时间才会执行,而且只会执行一次。

举个栗子:

 setTimeout(function(){console.log("1")},500)console.log("2")setTimeout(function(){console.log("3")},300)setTimeout(function(){console.log("5")},0)console.log("4")

从输出结果中,我们就可以看书JS执行的顺序,2和4都为主队列的同步任务,一开始就执行,执行顺序是从上到下。

setTimeout()中的函数,无论写在JS代码中的哪个位置,设置的时间即使是0,都为异步执行,在任务队列中,从主线程执行一开始,就进行计时,一旦主线程空闲,时间短的就立即加入到主线程开始执行,时间长的依然在等待。所以根据设定的等待时间,执行顺序为5,3,1

利用setInterval()实现异步执行

定时器的执行原理与延时器相似,只是不清除定时器,他就会反复执行。

异步执行的两个必要条件就是:

  1.  主队列空闲     
  2.  到达执行时间

通过上面的例子大家应该就懂了定时器的执行规则,下面我们再详细的分析一下为什么是这样的一个规则,他是与浏览器的执行规则有关系的。

-------------------------------------回到主题,继续剖析------------------------------------ 

浏览器的执行原理是什么呢?

浏览器的多线程:

JS是单线程的,但是对于浏览器来说JS的执行只不过是在浏览器众多现成中的一条,我们称之为JS引擎线程。而浏览器的其他线程则是通过JS引擎线程在执行到某个特定的功能之后指定给浏览器的对应线程

同样类似的栗子:

setTimeout(console.log('定时器!'),0);
console.log("测试")

这个结果大家应该都知道了,先打印测试字样,后打印定时器字样。

原理:

首先JS线程读取到setTimeout定时器,这个时候就会执行浏览器的线程,然后跳过定时器继续执行,这个时候你就看到了弹出框的内容为测试,然后因为定时器的时间为0,所以一执行定时器线程就会即可将弹出框为定时器字样的任务添加到主线程(JS引擎线程)的队列之后,等待JS引擎的调用,这个时候我们看到的结果是先弹出测试,然后再弹出定时器

setTimeout我们可以再次定义为:

在指定时间内, 将任务放入事件队列,等待js引擎空闲后被执行.

-------------------------讲完原理还不够,定时器的this指向是啥?------------------------- 

    var name = 'my name is window';var obj = {name: 'my name is obj',fn: function () {// var that = this; 可以在此处定义一个this,改变this指向setTimeout(function () {console.log(this.name);   //my name is window 定时器中this默认指向windowconsole.log(that.name)    //my name is obj }, 1000)// 也可以使用箭头函数改变this指向// setTimeout(()=> {//     console.log(this.name);   //my name is obj// }, 1000)}    }obj.fn()

在setTimeout内部,this绑定采用默认绑定规则,也就是说,在非严格模式下,this会指向window;而在严格模式下,this指向undefined

学会定时器的原理后,来个小测试~~~~~ 

for (var i = 0; i < 5; i++) {console.log(i);setTimeout(function timer() {console.log(i);}, i * 1000);
}  //依次输出:0, 1, 2, 3, 4  接着输出5个5

稍微解释一下啦:javascript是单线程语言,只有主线程上的所有同步任务执行完毕,主线程才会读取任务队列上的异步任务。for循环属于同步任务,而定时器属于异步任务。所以会在for循环结束之后才开始执行定时器的代码。因此会输出5个5。

如果帮到你了,请点个赞呦~~~

js定时器原理的深度剖析相关推荐

  1. C++ STL deque 容器底层实现原理(深度剖析)

    事实上,STL 中每个容器的特性,和它底层的实现机制密切相关,deque 自然也不例外.<C++ STL deque容器>一节中提到,deque 容器擅长在序列的头部和尾部添加或删除元素. ...

  2. golang延时_Golang 定时器底层实现深度剖析

    本文将基于 Golang 源码对 Timer 的底层实现进行深度剖析.主要包含以下内容: 1. Timer 和 Ticker 在 Golang 中的底层实现细节,包括数据结构等选型. 2. 分析 ti ...

  3. python中‘with xxx as xxx :’原理的深度剖析

    一.with对文件读取写入等操作: 以下代码演示了Python基本的文件操作,包括 open,read,write: 输出结果为: 读文件: 要以读文件的模式打开一个文件对象,使用Python内置的o ...

  4. 天线开路短路检测原理_深度剖析开短路测试原理

    开短路测试应用非常的广泛, 只要特别的指出相关行业, 所谓的开短路测试, 都是指测试邦定线的开短路测试, IC 的开短路测试. 开短路测试,是测试工程师需要掌握的最基本的技能,通常被称为 conTIn ...

  5. 【微信小程序控制硬件④】 深度剖析微信公众号配网 Airkiss 原理与过程,esp8266如何自定义回调参数给微信,实现绑定设备第一步!(附带源码)

    [微信小程序控制硬件第1篇 ] 全网首发,借助 emq 消息服务器带你如何搭建微信小程序的mqtt服务器,轻松控制智能硬件! [微信小程序控制硬件第2篇 ] 开始微信小程序之旅,导入小程序Mqtt客户 ...

  6. Mysql binlog应用场景与原理深度剖析

    1 基于binlog的主从复制 Mysql 5.0以后,支持通过binary log(二进制日志)以支持主从复制.复制允许将来自一个MySQL数据库服务器(master) 的数据复制到一个或多个其他M ...

  7. 好文推荐 | MySQL binlog应用场景与原理深度剖析

    作者:田守枝 来自:田守枝的博客(公众号) 本文深入介绍Mysql Binlog的应用场景,以及如何与MQ.elasticsearch.redis等组件的保持数据最终一致.最后通过案例深入分析binl ...

  8. git原理详解与实操指南_全网最精:学git一套就够了,从入门到原理深度剖析

    以上资源收集至互联网 如有侵权请联系删除 资源获取方式 扫码关注资源库公众号 回复密码'20190812' 即可获得 截图展示 课程信息 课程难度:中级 学习人数:148352 课程状态:已完结 时长 ...

  9. 深度剖析浏览器渲染性能原理,你到底知道多少?

    深度剖析浏览器渲染性能原理,你到底知道多少? 渲染卡顿是怎么回事? 网页不仅应该被快速加载,同时还应该流畅运行,比如快速响应的交互,如丝般顺滑的动画等. 大多数设备的刷新频率是60次/秒,也就说是浏览 ...

  10. 唯一插件化Replugin源码及原理深度剖析--插件的安装、加载原理

    上一篇 唯一插件化Replugin源码及原理深度剖析–唯一Hook点原理 在Replugin的初始化过程中,我将他们分成了比较重要3个模块,整体框架的初始化.hook系统ClassLoader.插件的 ...

最新文章

  1. 虚拟化方案应用场景及优劣
  2. springmvc如何访问静态文件,例如jpg,js,css
  3. Linux中如何安装MySQL详细步骤
  4. linux常用命令:top 命令
  5. excel可以处理html吗,处理包含XML/HTML元素的Excel文件
  6. MySQL5.7的搭建以及SSL证书
  7. SDL2源代码分析7:显示(SDL_RenderPresent())
  8. (转)Mahout Kmeans Clustering 学习
  9. JavaScript 学习计划
  10. 潘正磊: 做最好、最美的你
  11. Eureka/Zookeeper/Consul三种注册中心的区别
  12. [matlab数字图像处理10]对一副图像进行二值化,ostu算法等
  13. SAP ABAP BAPI_MATERIAL_AVAILABILITY 查询可用库存
  14. 暑期计算机数学培训心得体会,关于暑期培训心得体会三篇
  15. 2021计算机夏令营保研经历(中科院计算所,南京大学人工智能学院等)
  16. 上市公司股息红利差别化个人所得税政策
  17. 网站favicon图标的制作
  18. Python 将网易云歌单迁移到QQ音乐
  19. Java EE版本的eclipse的下载
  20. 数据结构:树和二叉树 思维导图

热门文章

  1. Ubuntu配置adb
  2. javascript DOM 操作基础知识小结
  3. OCR识别提取图片中文字原理
  4. poi导出使用HSSFWorkbook行数超出
  5. 这么多年的土豆都白吃了!土豆还能这么做,太香了
  6. 梦幻岛颠覆式变革NFT,探索实体与数字的双轨价值
  7. 一名数据分析师的工作职责和需要掌握的基本知识
  8. 大数据开发工程师岗位职责
  9. java的测试岗位_JAVA测试岗位职责
  10. Python正则表达式