简单通过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 有趣而诡异的数组
Apr 06 Javascript
JQuery 选项卡效果(JS与HTML的分离)
Apr 01 Javascript
对jQuery的事件绑定的一些思考(补充)
Apr 20 Javascript
JavaScript中的Truthy和Falsy介绍
Jan 01 Javascript
js设置document.domain实现跨域的注意点分析
May 21 Javascript
使用Object.defineProperty实现简单的js双向绑定
Apr 15 Javascript
浅析Javascript的自动分号插入(ASI)机制
Sep 29 Javascript
Angular2 http jsonp的实例详解
Aug 31 Javascript
jQuery实现的form转json经典示例
Oct 10 jQuery
仿淘宝JSsearch搜索下拉深度用法
Jan 15 Javascript
如何解决js函数防抖、节流出现的问题
Jun 17 Javascript
layui输入框中只允许输入整数的实现方法
Sep 18 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
phpfans留言版用到的数据操作类和分页类
2007/01/04 PHP
php打印输出棋盘的实现方法
2014/12/23 PHP
Laravel中Facade的加载过程与原理详解
2017/09/22 PHP
php实现的三个常用加密解密功能函数示例
2017/11/06 PHP
php array 转json及java 转换 json数据格式操作示例
2019/11/13 PHP
YUI 读码日记之 YAHOO.util.Dom - Part.1
2008/03/22 Javascript
jQuery 学习 几种常用方法
2009/06/11 Javascript
js或css文件后面跟参数的原因说明
2010/01/09 Javascript
jquery简单实现滚动条下拉DIV固定在头部不动
2013/11/25 Javascript
javascript间隔定时器(延时定时器)学习 间隔调用和延时调用
2014/01/13 Javascript
js判断数据类型如判断是否为数组是否为字符串等等
2014/01/15 Javascript
详解JavaScript的表达式与运算符
2015/11/30 Javascript
jQuery实现放大镜效果实例代码
2016/03/17 Javascript
BootStrap使用file-input插件上传图片的方法
2016/09/05 Javascript
JavaScript动态绑定详解
2017/09/14 Javascript
vue2里面ref的具体使用方法
2017/10/27 Javascript
Vue不能检测到Object/Array更新的情况的解决
2018/06/26 Javascript
vue生成文件本地打开查看效果的实例
2018/09/06 Javascript
详解webpack之图片引入-增强的file-loader:url-loader
2018/10/08 Javascript
详解小程序开发经验:多页面数据同步
2019/05/18 Javascript
uni-app 自定义底部导航栏的实现
2020/12/11 Javascript
[07:31]DOTA2卡尔工作室 英雄介绍主宰篇
2013/06/25 DOTA
[46:04]Liquid vs VP Supermajor决赛 BO 第四场 6.10
2018/07/05 DOTA
python发腾讯微博代码分享
2014/01/10 Python
python获取当前时间对应unix时间戳的方法
2015/05/15 Python
flask入门之文件上传与邮件发送示例
2018/07/18 Python
Python如何使用k-means方法将列表中相似的句子归类
2019/08/08 Python
Windows 下python3.8环境安装教程图文详解
2020/03/11 Python
关于前端上传文件全面基础扫盲贴(入门)
2019/08/01 HTML / CSS
土木工程毕业生推荐信
2013/10/28 职场文书
创业者迈进成功第一步:如何写创业计划书?
2014/03/22 职场文书
小学安全教育月活动总结
2014/07/07 职场文书
行政专员岗位职责说明书
2014/07/30 职场文书
2014年青年教师工作总结
2014/12/17 职场文书
Nginx工作原理和优化总结。
2021/04/02 Servers
Golang 获取文件md5校验的方法以及效率对比
2021/05/08 Golang