简单通过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实现点击文字可编辑并修改保存至数据库
Apr 15 Javascript
javascript中加号(+)操作符的一些神奇作用
Jun 06 Javascript
jQuery增加自定义函数的方法
Jul 18 Javascript
jQuery+jsp下拉框联动获取本地数据的方法(附源码)
Dec 03 Javascript
瀑布流的实现方式(原生js+jquery+css3)
Jun 28 Javascript
浅谈vue路径优化之resolve
Oct 13 Javascript
小程序云开发获取不到数据库记录的解决方法
May 18 Javascript
解决layui数据表格Date日期格式的回显Object的问题
Sep 19 Javascript
jQuery实现简单弹幕效果
Nov 28 jQuery
如何在vue项目中嵌入jsp页面的方法(2种)
Feb 06 Javascript
原生JS实现多条件筛选
Aug 19 Javascript
Nuxt的动态路由和参数校验操作
Nov 09 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
thinkPHP使用pclzip打包备份mysql数据库的方法
2016/04/30 PHP
对比PHP对MySQL的缓冲查询和无缓冲查询
2016/07/01 PHP
laravel框架中表单请求类型和CSRF防护实例分析
2019/11/23 PHP
javascript网页关闭时提醒效果脚本
2008/10/22 Javascript
自己写了一个展开和收起的多更能型的js效果
2013/03/05 Javascript
一个简单的瀑布流效果(主体形式自写)
2013/05/27 Javascript
JavaScript实现查找字符串中第一个不重复的字符
2014/12/29 Javascript
ajax+jQuery实现级联显示地址的方法
2015/05/06 Javascript
全面解析Bootstrap弹窗的实现方法
2015/12/01 Javascript
Bootstrap导航栏各元素操作方法(表单、按钮、文本)
2015/12/28 Javascript
详解jQuery中的deferred对象的使用(一)
2016/05/27 Javascript
纯原生js实现table表格的增删
2017/01/05 Javascript
微信小程序基于slider组件动态修改标签透明度的方法示例
2017/12/04 Javascript
Vue通过URL传参如何控制全局console.log的开关详解
2017/12/07 Javascript
vue-cli创建的项目,配置多页面的实现方法
2018/03/15 Javascript
vue中各种通信传值方式总结
2019/02/14 Javascript
详解Nuxt内导航栏的两种实现方式
2020/04/16 Javascript
详解Webpack4多页应用打包方案
2020/07/16 Javascript
Pandas:DataFrame对象的基础操作方法
2018/06/07 Python
Python实现读取机器硬件信息的方法示例
2018/06/09 Python
PythonWeb项目Django部署在Ubuntu18.04腾讯云主机上
2019/04/01 Python
Python3.5基础之NumPy模块的使用图文与实例详解
2019/04/24 Python
python实现随机漫步方法和原理
2019/06/10 Python
Python搭建Spark分布式集群环境
2019/07/05 Python
浅谈django url请求与数据库连接池的共享问题
2019/08/29 Python
TensorFlow2.0矩阵与向量的加减乘实例
2020/02/07 Python
Keras在训练期间可视化训练误差和测试误差实例
2020/06/16 Python
解决pyinstaller 打包exe文件太大,用pipenv 缩小exe的问题
2020/07/13 Python
基于python+selenium自动健康打卡的实现代码
2021/01/13 Python
canvas之万花筒效果的简单实现(推荐)
2016/08/16 HTML / CSS
HTML5 device access 设备访问详解
2018/05/24 HTML / CSS
实例教程 利用html5和css3打造一款创意404页面
2014/10/20 HTML / CSS
html5小程序飞入购物车(抛物线绘制运动轨迹点)
2020/10/19 HTML / CSS
建筑专业自荐信范文
2014/01/05 职场文书
业务员年终工作总结2015
2015/05/28 职场文书
Vue中foreach数组与js中遍历数组的写法说明
2021/06/05 Vue.js