调用堆栈
栏目: JavaScript · 发布时间: 5年前
内容简介:无意之中发现一个很不错的项目:意味着js在同一时间段内只能做一件事情,意味着它只有一个调用堆栈(call stack)。为什么呢?因为js是浏览器脚本语言,主要用来处理与用户进行的操作、操作DOM之类的事情,如果它有多个线程,比如线程A想添加DOM节点,线程B想删除该DOM节点,那它该何去何从呢?同步任务和异步任务分别进入不同的“场所”。同步进入主线程,异步进入Event Table并注册回调函数,然后将其移入进Event Queue中。主线程内的任务执行完毕直至为空后,再去Event Queue读取对应的
无意之中发现一个很不错的项目: 中文地址 、 原版英文地址 ,刚好适合自己巩固加深理解JavaScript,于是定下一个小目标:总共33个知识点,每天攻克一个,一个月后再来回首感悟!
内容:
1.js是一个单线程的编程语言
意味着js在同一时间段内只能做一件事情,意味着它只有一个调用堆栈(call stack)。为什么呢?因为js是浏览器脚本语言,主要用来处理与用户进行的操作、操作DOM之类的事情,如果它有多个线程,比如线程A想添加DOM节点,线程B想删除该DOM节点,那它该何去何从呢?
2.Event Loop(事件循环)
上图来自于优秀的这篇文章同步任务和异步任务分别进入不同的“场所”。同步进入主线程,异步进入Event Table并注册回调函数,然后将其移入进Event Queue中。主线程内的任务执行完毕直至为空后,再去Event Queue读取对应的函数,进入主线程。
上述过程不断重复,就是 Event Loop(事件循环)
3.宏任务(macro tasks)和微任务(micro tasks)
-
js中有两类任务队列:宏任务(macro tasks)和微任务(micro tasks).
- 宏任务:script(全局任务)、setTimeout、setInterval、setImmediate、I/O、UI rendering
- 微任务:process.nextTick、Promise, Object.observer, MutationObserver
4.一些面试题
setTimeout(_ => console.log(4)) new Promise(resolve => { resolve() console.log(1); }).then(_ => { console.log(3); }) console.log(2); 复制代码
- setTimeout属于宏任务,new Promise属于同步任务,于是直接输出 1
- 后面的.then()加入微任务中,接下来直接输出 2
- 微任务.then()比setTimeout先执行,故输出 3
- 最后输出 4
-
敲黑板:
- setTimeout的作用是等待给定的时间后为它的回调产生一个新的宏任务
- Promise.then则是具有代表性的微任务
- new Promise在实例化的过程中所执行的代码都是 同步 进行的,而then中注册的回调才是 异步 执行的
- 同步代码执行完成后才回去检查是否有异步任务完成,并执行对应的回调,而 微任务又会在宏任务之前执行
setTimeout(function(){ console.log('定时器开始啦') }); new Promise(function(resolve){ console.log('马上执行for循环啦'); for(var i = 0; i < 10000; i++){ i == 99 && resolve(); } }).then(function(){ console.log('执行then函数啦') }); console.log('代码执行结束'); 复制代码
执行结果:马上执行for循环啦,代码执行结束,执行then函数啦, 定时器开始啦。(解析步骤同上!)
console.log(1); setTimeout(() => { console.log(2); Promise.resolve().then(() => { console.log(3) }); }); new Promise((resolve, reject) => { console.log(4) resolve(5) }).then((data) => { console.log(data); }) setTimeout(() => { console.log(6); }) console.log(7); 复制代码
- 执行结果:1、4、7、5、2、3、6
-
敲黑板:
- 执行全局Script,直接输出 1 ,后面的setTimeout为宏任务
- new Promise相当于同步任务,输出 4 ,后面的.then()加入到微任务队列中,后面的setTimeout为宏任务
- 接着执行全局Script,直接输出 7
- 执行完所有的宏任务后,接着在微任务队列中的所有,输出 5
- 接着执行剩下的宏任务,输出 2
- 然后执行上一步宏任务后产生的微任务,输出 3
- 最后执行最后一个setTimeout宏任务,输出 6
console.log('script start'); setTimeout(function() { console.log('setTimeout'); }, 0); Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); }); console.log('script end'); 复制代码
- 执行结果:script start、script end、 promise1、 promise2、setTimeout
-
敲黑板:
- 全局Script任务,直接输出:script start、script end
- 接下来执行微任务,输出promise1、promise2
- 最后输出setTimeout
- 所有微任务总会在下一个宏任务之前全部执行完毕
以上所述就是小编给大家介绍的《调用堆栈》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 前端进阶(第一期)-调用堆栈笔记
- [golang]如何看懂调用堆栈
- GDB入门教程之查看函数调用堆栈
- JavaScript的工作原理:引擎,运行时和调用堆栈
- 【译】JavaScript的工作原理:引擎,运行时和调用堆栈的概述
- 用于在高性能计算应用中检测异常调用堆栈树的可视分析框架 (A Visual Analytics Framework for th...
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Making Things See
Greg Borenstein / Make / 2012-2-3 / USD 39.99
Welcome to the Vision Revolution. With Microsoft's Kinect leading the way, you can now use 3D computer vision technology to build digital 3D models of people and objects that you can manipulate with g......一起来看看 《Making Things See》 这本书的介绍吧!