调用堆栈

栏目: 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
    • 所有微任务总会在下一个宏任务之前全部执行完毕

以上所述就是小编给大家介绍的《调用堆栈》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入理解 Flask

深入理解 Flask

[美]Jack Stouffer / 苏丹 / 电子工业出版社 / 2016-7-1 / 79.00

Flask 是一种具有平缓学习曲线和庞大社区支持的微框架,利用它可以构建大规模的web应用。学习上手Flask非常轻松,但要深入理解却并不容易。 本书从一个简单的Flask应用开始,通过解决若干实战中的问题,对一系列进阶的话题进行了探讨。书中使用MVC(模型-视图-控制器)架构对示例应用进行了转化重构,以演示如何正确地组织应用代码结构。有了可扩展性强的应用结构之后,接下来的章节使用Flask......一起来看看 《深入理解 Flask》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具