简单通过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 相关文章推荐
基于JQuery的一句代码实现表格的简单筛选
Jul 26 Javascript
JavaScript中去掉数组中的重复值的实现方法
Aug 03 Javascript
jquery动态加载select下拉框示例代码
Dec 10 Javascript
js实现字符串转日期格式的方法
May 20 Javascript
原生js实现模拟滚动条
Jun 15 Javascript
在JavaScript中对HTML进行反转义详解
May 18 Javascript
jquery点击展示与隐藏更多内容
Dec 03 Javascript
JavaScript中运算符规则和隐式类型转换示例详解
Sep 06 Javascript
Angular数据绑定机制原理
Apr 17 Javascript
JavaScript事件委托原理与用法实例分析
Jun 07 Javascript
vue 实现数字滚动增加效果的实例代码
Jul 06 Javascript
vue组件之间通信实例总结(点赞功能)
Dec 05 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编程中字符串处理的5个技巧小结
2007/11/13 PHP
解析在zend Farmework下如何创立一个FORM表单
2013/06/28 PHP
php获取英文姓名首字母的方法
2015/07/13 PHP
php使用 readfile() 函数设置文件大小大小的方法
2017/08/11 PHP
js 动态添加标签(新增一行,其实很简单,就是几个函数的应用)
2009/03/26 Javascript
javascript addBookmark 加入收藏 多浏览器兼容
2009/08/15 Javascript
Firefox/Chrome/Safari的中可直接使用$/$$函数进行调试
2012/02/13 Javascript
解读JavaScript中 For, While与递归的用法
2013/05/07 Javascript
提高jQuery性能的十个诀窍
2013/11/14 Javascript
jQuery实现点击图片翻页展示效果的方法
2015/02/16 Javascript
jQuery插件bxSlider实现响应式焦点图
2015/04/12 Javascript
jquery表单提交带错误信息提示效果
2017/03/09 Javascript
AngularJS使用拦截器实现的loading功能完整实例
2017/05/17 Javascript
Node.js编写CLI的实例详解
2017/05/17 Javascript
JavaScript设计模式之代理模式详解
2017/06/09 Javascript
Vue中父组件向子组件通信的方法
2017/07/11 Javascript
在weex中愉快的使用scss的方法步骤
2020/01/02 Javascript
Vue.js使用axios动态获取response里的data数据操作
2020/09/08 Javascript
微信小程序实现日历签到
2020/09/21 Javascript
[01:33:07]VGJ.T vs Newbee Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
Python程序语言快速上手教程
2012/07/18 Python
Python基于PycURL实现POST的方法
2015/07/25 Python
Python while 循环使用的简单实例
2016/06/08 Python
Python3.遍历某文件夹提取特定文件名的实例
2018/04/26 Python
详细整理python 字符串(str)与列表(list)以及数组(array)之间的转换方法
2019/08/30 Python
TensorFlow查看输入节点和输出节点名称方式
2020/01/04 Python
解决Tensorboard可视化错误:不显示数据 No scalar data was found
2020/02/15 Python
Yummie官方网站:塑身衣和衣柜必需品
2019/10/29 全球购物
排序都有哪几种方法?请列举。用JAVA实现一个快速排序
2014/02/16 面试题
学雷锋月活动总结
2014/04/25 职场文书
健康教育评估方案
2014/05/25 职场文书
校运会新闻稿
2015/07/17 职场文书
银行柜员工作心得体会
2016/01/23 职场文书
2019军训心得体会
2019/06/27 职场文书
Canvas如何做个雪花屏版404的实现
2021/09/25 HTML / CSS
Go语言怎么使用变长参数函数
2022/07/15 Golang