用几道面试题来看JavaScript执行机制


Posted in Javascript onApril 30, 2021

前面的话

根据JavaScript的运行环境,锁定它为单线程,任务需要排队执行,如果网站资源比较大,这样会导致浏览器加载会很慢,但实际上并没有,大家肯定立刻想到了同步和异步。

所谓的同步和异步也是在排队,只是排队的地方不同。

同步和异步

同步任务进入主线程排队,异步任务进入事件队列中排队

同步任务和异步任务进入到不同的队列中,也就是上面讲的在不同地方排队。

同步任务进入主线程,异步任务进入事件队列,主线程任务执行完毕,事件队列中有等待执行的任务进入主线程执行,直到事件队列中任务全部执行完毕。

开胃菜

console.log('a')

setTimeout(function(){
    console.log('b')
}, 200)

setTimeout(function(){
    console.log('c')
}, 0)

console.log('d')

a d c b

从上到下,该进入主线程的进入主线程,该进入事件队列的进入事件队列。

那么主线程中存在console.log('a')和console.log('d'),定时器setTimeout延迟一段时间执行,顾名思义异步任务进入事件队列中,等待主线程任务执行完毕,再进入主线程执行。

定时器的延迟时间为0并不是立刻执行,只是代表相比于其他定时器更早的进入主线程中执行。

加一盘

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i)
    }, 1000)
}

结果:十个10

每次for循环遇到setTimeout将其放入事件队列中等待执行,直到全部循环结束,i作为全局变量当循环结束后i = 10,再来执行setTimeout时i的值已经为10, 结果为十个10。

将var改为let,变量作用域不同,let作用在当前循环中,所以进入事件队列的定时器每次的i不同,最后打印结果会是 0 1 2...9。

宏任务 微任务

除了经常说的同步任务和异步任务之外,更可分为宏任务,微任务

主要宏任务:整段脚本scriptsetTimeoutsetTimeout...

主要微任务:promise.then...

执行流程:

1.整段脚本script作为宏任务开始执行

2.遇到微任务将其推入微任务队列,宏任务推入宏任务队列

3.宏任务执行完毕,检查有没有可执行的微任务

4.发现有可执行的微任务,将所有微任务执行完毕

5.开始新的宏任务,反复如此直到所有任务执行完毕

来一盘Promise

const p = new Promise(resolve => {
    console.log('a')
    resolve()
    console.log('b')
})

p.then(() => {
    console.log('c')
})

console.log('d')

结果:a b d c

1.整段script进入宏任务队列开始执行

2.promise创建立即执行,打印ab

3.遇到promise.then进入微任务队列

4.遇到console.log('d')打印d

5.整段代码作为宏任务执行完毕,有可执行的微任务,开始执行微任务,打印c。

setTimeout(function(){
    console.log('setTimeout')
}, 0)

const p = new Promise(resolve => {
    console.log('a')
    resolve()
    console.log('b')
})

p.then(() => {
    console.log('c')
})

console.log('d')

结果:a b d c setTimeout

1.setTimeout进入宏任务队列

2.promise创建立即执行,打印ab

3.遇到promise.then进入微任务队列

4.遇到console.log('d')打印d

5.有可执行的微任务,打印c

6.微任务执行完毕,开始执行新的宏任务,setTimeout开始执行,打印setTimeout

setTimeout(function(){
    console.log('setTimeout')
}, 0)

const p = new Promise(resolve => {
    console.log('a')
    resolve()
    console.log('b')
})

p.then(() => {
    console.log('c')
    setTimeout(function(){
        console.log('then中的setTimeout')
    }, 0)
})

console.log('d')

结果:a b d c setTimeout then中的setTimeout

1.同上

2.执行微任务打印c,遇到setTimeout将其推入宏任务队列中

3.定时器延迟时间相同,开始按照顺序执行宏任务,分别打印setTimeoutthen中的setTimeout

再加点定时器

console.log('a');

new Promise(resolve => {
    console.log('b')
    resolve()
}).then(() => {
    console.log('c')
    setTimeout(() => {
      console.log('d')
    }, 0)
})

setTimeout(() => {
    console.log('e')
    new Promise(resolve => {
        console.log('f')
        resolve()
    }).then(() => {
        console.log('g')
    })
}, 100)

setTimeout(() => {
    console.log('h')
    new Promise(resolve => {
        resolve()
    }).then(() => {
        console.log('i')
    })
    console.log('j')
}, 0)

结果:a b c h j i d e f g

1.打印a

2.promise立即执行,打印b

3.promise.then推入微任务队列

4.setTimeout推入宏任务队列

5.整段代码执行完毕,开始执行微任务,打印c,遇到setTimeout推入宏任务队列排队等待执行

6.没有可执行的微任务开始执行宏任务,定时器按照延迟时间排队执行

7.打印h j,promise.then推入微任务队列有

8.可执行的微任务,打印i,继续执行宏任务,打印d

9.执行延迟为100的宏任务,打印e f,执行微任务打印g,所有任务执行完毕

简单测试

console.log('start')

a().then(() => {
  console.log('a_then')
})

console.log('end')

function a() {
  console.log('a_function')
  return b().then((res) => {
    console.log('res', res)
    console.log('b_then')
    return Promise.resolve('a方法的返回值')
  })
}

function b() {
  console.log('b_function')
  return Promise.resolve('返回值')
}

结果:start a_function b_function end res 返回值 b_then a_then

根据上面例子的流程讲解来思考这个,加深理解

总结

  • JavaScript单线程,任务需要排队执行
  • 同步任务进入主线程排队,异步任务进入事件队列排队等待被推入主线程执
  • 行定时器的延迟时间为0并不是立刻执行,只是代表相比于其他定时器更早的被执行
  • 以宏任务和微任务进一步理解js执行机制
  • 整段代码作为宏任务开始执行,执行过程中宏任务和微任务进入相应的队列中
  • 整段代码执行结束,看微任务队列中是否有任务等待执行,如果有则执行所有的微任务,直到微任务队列中的任务执行完毕,如果没有则继续
  • 执行新的宏任务执行新的宏任务,凡是在执行宏任务过程中遇到微任务都将其推入微任务队列中执行
  • 反复如此直到所有任务全部执行完毕

以上就是用几道面试题来看JavaScript执行机制的详细内容,更多关于JavaScript执行机制的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
passwordStrength 基于jquery的密码强度检测代码使用介绍
Oct 08 Javascript
找出字符串中出现次数最多的字母和出现次数精简版
Nov 07 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(一)让静态人物动起来
Jan 23 Javascript
Jquery实现列表(隔行换色,全选,鼠标滑过当前行)效果实例
Jun 09 Javascript
jquery基础教程之数组使用详解
Mar 10 Javascript
jQuery如何封装输入框插件
Aug 19 Javascript
js canvas实现适用于移动端的百分比仪表盘dashboard
Jul 18 Javascript
Javascript 严格模式use strict详解
Sep 16 Javascript
详解React中传入组件的props改变时更新组件的几种实现方法
Sep 13 Javascript
JavaScript表格隔行变色和Tab标签页特效示例【附jQuery版】
Jul 11 jQuery
简述vue-cli中chainWebpack的使用方法
Jul 30 Javascript
JS获取动态添加元素的方法详解
Jul 31 Javascript
详解前端任务构建利器Gulp.js使用指南
Apr 30 #Javascript
浅谈node.js中间件有哪些类型
Apr 29 #Javascript
JavaScript实现简单图片切换
何时使用Map来代替普通的JS对象
详解Js模块化的作用原理和方案
详解JavaScript中的执行上下文及调用堆栈
JavaScript实现淘宝商品图切换效果
You might like
URL Rewrite的设置方法
2007/01/02 PHP
PHP开发中常见的安全问题详解和解决方法(如Sql注入、CSRF、Xss、CC等)
2014/04/21 PHP
PHP.ini中配置屏蔽错误信息显示和保存错误日志的例子
2014/05/12 PHP
jquery checkbox,radio是否选中的判断代码
2010/03/20 Javascript
javascript+mapbar实现地图定位
2010/04/09 Javascript
运用JQuery的toggle实现网页加载完成自动弹窗
2014/03/18 Javascript
jQuery中:disabled选择器用法实例
2015/01/04 Javascript
JavaScript中的small()方法使用详解
2015/06/08 Javascript
探究JavaScript函数式编程的乐趣
2015/12/14 Javascript
Node.js Streams文件读写操作详解
2016/07/04 Javascript
AngularJS解决ng界面长表达式(ui-set)的方法分析
2016/11/07 Javascript
jsonp跨域请求实现示例
2017/03/13 Javascript
Vue引用第三方datepicker插件无法监听datepicker输入框的值的解决
2018/01/27 Javascript
在vue中安装使用vux的教程详解
2018/09/16 Javascript
[10:07]2014DOTA2国际邀请赛 实拍选手现场观战DK对阵Titan
2014/07/12 DOTA
[03:09]2014DOTA2国际邀请赛 赛场上的美丽风景线 中国Coser也爱DOTA2
2014/07/20 DOTA
[31:47]夜魇凡尔赛茶话会 第三期01:选手知多少
2021/03/11 DOTA
使用py2exe在Windows下将Python程序转为exe文件
2016/03/04 Python
简单了解OpenCV是个什么东西
2017/11/10 Python
python实现生命游戏的示例代码(Game of Life)
2018/01/24 Python
python实现微信自动回复功能
2018/04/11 Python
Python3.x爬虫下载网页图片的实例讲解
2018/05/22 Python
Python使用folium excel绘制point
2019/01/03 Python
Python3爬虫之自动查询天气并实现语音播报
2019/02/21 Python
python实现文件助手中查看微信撤回消息
2019/04/29 Python
python如何控制进程或者线程的个数
2020/10/16 Python
使用CSS3中的calc()属性来以算式表达尺寸数值
2016/06/06 HTML / CSS
HTML5探秘:用requestAnimationFrame优化Web动画
2018/06/03 HTML / CSS
美国折扣网站:jClub
2017/08/07 全球购物
extern在函数声明中是什么意思
2014/01/19 面试题
2014乡镇班子个人对照检查材料思想汇报
2014/09/26 职场文书
付款委托书范本
2014/10/05 职场文书
二手车交易协议书标准版
2014/11/16 职场文书
2015年社区卫生工作总结
2015/04/21 职场文书
入党介绍人考察意见
2015/06/01 职场文书
开网店计划分析
2019/07/30 职场文书