1、前言了解
js本是单线程,但很多时候,单线程效率太慢,影响进度,于是又有了多进程的发展,当然这仅仅是在单线程里站队将其分解多步解决问题,这就开始有了异步任务的发展~
2、同步异步的了解
- 同步是指按照顺序执行的操作,当前一件事未完成之前,后面的事件都不能启动。
- 异步则不一样,异步就是指多件事情可以同时操作,不需要谁等谁。
- 同步就像是只有一个队列,该队列只有一个窗口可以解决问题,而异步就像是一个队列,但是队列中的每一项都有一个窗口可以解决问题。
同步异步区别
下面一张图说明
3、微观、宏观
- 这里只需要知道微观事件有哪些,微观事件是归类到微观队列里去的,主要有Promise.then的回掉函数、await后面的代码
- 宏观事件比较多,比如定时器、script块、IO设备等等
4、任务队列
- 事件执行的时候遇到异步操作就会提交给浏览器的API,而webAPI就会将其注册列表内,然后再根据优先级(各个浏览器优先级不一样)返回到任务队列里面
- 任务队列将其分成微观队列和宏观队列,对应的就是微观事件和宏观事件。
5、事件循环
js执行机制就是按照时间循环来执行的,下面是事件循环介绍:
- 1.进入到script标签,就进入到了第一次事件循环.
- 2.遇到同步代码,立即执行
- 3.遇到宏任务,放入到宏任务队列里.
- 4.遇到微任务,放入到微任务队列里.
- 5.执行完所有同步代码
- 6.执行微任务代码
- 7.微任务代码执行完毕,本次队列清空
寻找下一个宏任务,重复步骤1
6、代码实现
1)首先上一个简单的例子
<script type="text/javascript">
new Promise(function(resolve){
console.log(1)
for( var i=0 ; i<10000 ; i++ ){
i==9999 && resolve()
}
console.log(2)
}).then(function(){//promise的回掉函数
console.log(5)
});
setTimeout(function(){console.log(4)},0);
console.log(3);
</script>
上面代码执行顺序是怎样的呢,下面可以根据事件循环的机制走一遍
1)js在执行栈里执行事件(script就是第一个宏观任务,也就是执行栈)
2)先在执行栈里面执行事件,promise的函数主体是同步任务,故直接执行里面代码,可得到结果1、2,然后遇到了.then回掉函数将其返回给WebApl,WebApi再返回到微观队列。再往下执行遇到了setTimeout定时器,是宏观任务就将其返回到宏观队列的任务列表,之后再执行最后一步得到3
3)执行栈里的事件执行完毕后,先到该队列里找到是否有微观事件,咱们的微观任务队列里面有.then回掉函数,故可以先执行这个操作得到结果5
4)微观事件执行完毕,再到队列里查看是否有宏观事件,这时发现了定时器故执行后的结果4
5)不断的查看队列,直到队列为空即可
最后可以输出结果答案就是12354
按照以上步骤大家可以检测一下自己是否真正懂了,以下是一份稍微复杂的执行代码。
console.log('1');
setTimeout(function() {
console.log('2');
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
})
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8')
})
setTimeout(function() {
console.log('9');
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})
大家可以按照上面写的js的执行顺序去执行看自己是否真正理解掌握了
最后结果是1、7、8、2、4、5、9、11、12。
7、总结
不管是怎么复杂的事件,只要记住,先执行看到的,遇到异步操作先不管,先走执行栈里面的代码,执行完毕后再微观队列然后宏观队列。