调用堆栈

初衷:

无心之中发现一个很不错的项目:中文地址原版英文地址,恰好适合本身巩固加深理解JavaScript,因而定下一个小目标:总共33个知识点,天天攻克一个,一个月后再来回首感悟!javascript

后来(通过一天的实践后)就被啪啪打脸了,因为这个小目标是在空闲时间完成的,在兼顾自己工做的时候,天天更新一个知识点,现变成两天一个吧。java

内容:

1.js是一个单线程的编程语言

意味着js在同一时间段内只能作一件事情,意味着它只有一个调用堆栈(call stack)。为何呢?由于js是浏览器脚本语言,主要用来处理与用户进行的操做、操做DOM之类的事情,若是它有多个线程,好比线程A想添加DOM节点,线程B想删除该DOM节点,那它该何去何从呢?git

2.Event Loop(事件循环)

优秀的这篇文章
上图来自于优秀的这篇文章github

同步任务和异步任务分别进入不一样的“场所”。同步进入主线程,异步进入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函数啦, 定时器开始啦。(解析步骤同上!)
***promise

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);
  • 执行结果:一、四、七、五、二、三、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、 promise一、 promise二、setTimeout
● 全局Script任务,直接输出:script start、script end
    
    ● 接下来执行微任务,输出promise一、promise2
    
    ● 最后输出setTimeout
    
    ● 全部微任务总会在下一个宏任务以前所有执行完毕

结语:

看了好多篇优秀的文章,瞬间感受本身以前得有多**,多学习优秀者的优秀!今年开始,文章先发表在了掘金主页了哟,所以博客园就滞后点了~浏览器

懵***

相关文章
相关标签/搜索