85281643 2019-06-29
~先双手奉上这道题目~
async function async1() { console.log("async1 start"); await async2(); console.log("async1 end"); } async function async2() { console.log( 'async2'); } console.log("script start"); setTimeout(function () { console.log("settimeout"); },0); async1(); new Promise(function (resolve) { console.log("promise1"); resolve(); }).then(function () { console.log("promise2"); }); console.log('script end');
JS众所周知是单线程语言,Javascript引擎同一时刻只能执行一个代码块,使用Event Loop作为它的异步执行机制
那么Event Loop是如何实现异步呢,个人浅显的理解如下:
等主进程中的同步函数执行完毕后,轮询去执行异步队列中的异步函数
⚠️注意: setTimeOut并不是直接的把你的回掉函数放进上述的异步队列中去,而是在定时器的时间到了之后,把回掉函数放到执行异步队列中去。如果此时这个队列已经有很多任务了,那就排在他们的后面。这也就解释了为什么setTimeOut为什么不能精准的执行的问题了。setTimeOut执行需要满足两个条件:
1. 主进程必须是空闲的状态,如果到时间了,主进程不空闲也不会执行你的回掉函数 2. 这个回掉函数需要等到插入异步队列时前面的异步函数都执行完了,才会执行
理解了Eventloop异步实现的方式,再来补充一下promise、async/await
首先,new Promise是同步的任务,会被放到主进程中去立即执行。而.then()函数是异步任务会放到异步队列中去,那什么时候放到异步队列中去呢?当你的promise状态结束的时候,就会立即放进异步队列中去了。如果你要问他和setTimeOut谁当进去的快,要从下面两个方面考虑:
1. promise结束时。.then内函数插入异步队列的时间与setTimeOut的回掉函数插入队列的时间,谁的早,谁的就最快2. **如果promise是同步的而setTimeOut时间是0,那么是promise先执行**。至于什么,查了很多的资料,了解到:一个浏览器环境只能有一个事件循环,而一个事件循环可以有多个任务队列。settimeout所在的队列与promise.then()的队列不同,面对此种情况,v8实现的时候会先从promise.then()的队列取任务,但是并没有很理解,如果有大佬愿意指点迷津,请留言告知