简单通过settimeout看javascript的运行机制


Posted in Javascript onMay 10, 2019

前言

我们知道JS是一个单线程的语言,而且其运行机制比较特殊。

下面我们通过settimeout的几个示例来展现javascript的运行机制的特殊点

示例1

console.log(1);
setTimeout(function(){
 console.log(2);
},0);
console.log(3);
// 打印出 1 3 2

示例2

console.log('1');
setTimeout(function(){
 console.log('2');
},0);
while(1){}
// 打印出1,然后浏览器卡死,不会打印出2

javascript会先把需要运行的内容放到任务队列中

但是如果遇到settimeout,会认为这是个异步任务,会先放到异步队列中

浏览器会先执行同步任务,等到同步任务执行完之后,再查看异步队列

如果异步队列中的任务的执行时机到了,浏览器就会把任务放到同步队列中去。

即:

异步任务一定在同步任务之后执行。

示例3

for(var i = 0; i < 4; i++){
 setTimeout(function() {
  console.log(i);
 }, 1000);
}
// 打印 4 4 4 4

为什么打印出的是4 4 4 4呢?

因为浏览器会先执行for循环

每执行一次for循环,都把一个settimeout压入异步队列

1000毫秒之后,执行settimeout里的方法的时候,i的值已经是4了。

如果要打印0 1 2 3怎么办呢?

利用闭包的特性,把i缓存到一个temp值里

for(var i = 0; i < 4; i++){
 (function(temp){
  setTimeout(function() {
   console.log(temp);
  }, 1000);
 })(i);
}
// 打印 0 1 2 3

这样做等于是每一次for循环都新建了一个匿名函数,i的值被存入了这个匿名函数的内存里。

理解了闭包的同学一定可以理解这一点。

示例4

我们知道ES6引入了新的关键字let

在这里,let有一个新的特性

for(let i = 0; i < 4; i ++){
 setTimeout(function(){
  console.log(i); 
 }, 1000);
}
// 打印 0 1 2 3

示例4与示例3只有var和let这个地方有区别,但是打印出来的结果却完全不同

这是因为let是一个块级作用域

let定义的i,对于每一个for循环的执行来说都是一个全新的i(使用不同的内存地址)

所以打印的时候可以得到0 1 2 3

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
javascript中的有名函数和无名函数
Oct 17 Javascript
javascript 写类方式之二
Jul 05 Javascript
JQuery Ajax通过Handler访问外部XML数据的代码
Jun 01 Javascript
javascript基础知识大集锦(一) 推荐收藏
Jan 13 Javascript
JS短路原理的应用示例 精简代码的途径
Dec 13 Javascript
2014 年最热门的21款JavaScript框架推荐
Dec 25 Javascript
jQuery实现联动下拉列表查询框
Jan 04 Javascript
Angular2+如何去除url中的#号详解
Dec 20 Javascript
详解swipe使用及竖屏页面滚动方法
Jun 28 Javascript
vscode中vue-cli项目es-lint的配置方法
Jul 30 Javascript
解决layui-open关闭自身窗口的问题
Sep 10 Javascript
vue中使用带隐藏文本信息的图片、图片水印的方法
Apr 24 Javascript
详解js实时获取并显示当前时间的方法
May 10 #Javascript
JS获取本地地址及天气的方法实例小结
May 10 #Javascript
Vue keepAlive 数据缓存工具实现返回上一个页面浏览的位置
May 10 #Javascript
vue无限轮播插件代码实例
May 10 #Javascript
js中的深浅拷贝问题简析
May 10 #Javascript
解决cordova+vue 项目打包成APK应用遇到的问题
May 10 #Javascript
详解jQuery如何实现模糊搜索
May 10 #jQuery
You might like
用PHP实现的生成静态HTML速度快类库
2007/03/31 PHP
修改php.ini不生效问题解决方法(上传大于8M的文件)
2013/06/14 PHP
php调用自己java程序的方法详解
2016/05/13 PHP
php is_writable判断文件是否可写实例代码
2016/10/13 PHP
PHP多维数组元素操作类的方法
2016/11/14 PHP
PHP+ajax实现获取新闻数据简单示例
2018/05/08 PHP
css3实现背景模糊的三种方式
2021/03/09 HTML / CSS
JS获取IP、MAC和主机名的五种方法
2013/11/14 Javascript
使用JQuery FancyBox插件实现图片展示特效
2015/11/16 Javascript
JavaScript解八皇后问题的方法总结
2016/06/12 Javascript
BootStrap轻松实现微信页面开发代码分享
2016/10/21 Javascript
微信小程序 wxapp地图 map详解
2016/10/31 Javascript
基于vue的下拉刷新指令和滚动刷新指令
2016/12/23 Javascript
理解javascript中的闭包
2017/01/11 Javascript
jQuery无刷新上传之uploadify简单代码
2017/01/17 Javascript
详解vue的数据binding绑定原理
2017/04/12 Javascript
简化vuex的状态管理方案的方法
2018/06/02 Javascript
Python通过DOM和SAX方式解析XML的应用实例分享
2015/11/16 Python
Python通过matplotlib画双层饼图及环形图简单示例
2017/12/15 Python
python如何统计序列中元素
2020/07/31 Python
python机器人运动范围问题的解答
2019/04/29 Python
OpenCV python sklearn随机超参数搜索的实现
2020/01/17 Python
django xadmin 管理器常用显示设置方式
2020/03/11 Python
Pytorch使用PIL和Numpy将单张图片转为Pytorch张量方式
2020/05/25 Python
Keras中的多分类损失函数用法categorical_crossentropy
2020/06/11 Python
keras分类之二分类实例(Cat and dog)
2020/07/09 Python
3D动画《斗罗大陆》上线当日播放过亿
2021/03/16 国漫
css3.0 图形构成实例练习二
2013/03/19 HTML / CSS
amazeui页面分析之登录页面的示例代码
2020/08/25 HTML / CSS
行政经理岗位职责
2013/11/09 职场文书
财务主管自我鉴定
2014/01/17 职场文书
战友聚会邀请函
2014/01/18 职场文书
助残日活动总结
2014/08/27 职场文书
老人节标语大全
2014/10/08 职场文书
MySQL 1130异常,无法远程登录解决方案详解
2021/08/23 MySQL
关于Redis的主从复制及哨兵问题
2022/06/16 Redis