JavaScript中的Event Loop小了解
我也不知道这是个啥图
Event Loop
Event Loop定义了浏览器执行你写的代码的顺序。我们都知道浏览器在执行代码的时候,并不肯定按照你写的顺序来执行,由于这里边可能存在异步执行,而且可能有多个异步代码,还有可能有多种异步代码。那么当这种情况存在的时候,浏览器就需要有一种机制,来判断当前应当执行哪部分代码。
而后,还需要知道Event Loop机制中两个任务,第一个是宏任务MacroTask,第二个是微任务MicroTask,还有一个叫执行栈的东西。Event Loop的机制就是先让执行栈执行完宏任务队列中的所有任务,而后再执行微任务队列中的所有任务,完了继续循环。
- 执行栈:所有的js代码都会被放到执行栈中依次执行。
- 宏任务:简单点说,就是一串js代码,但是被划分为了宏任务。哪些会被划分为宏任务呢?包括
script标签中代码setTimeoutsetIntervalI/OUI渲染postMessage等(并没有归纳完)。宏任务可以继续产生宏任务/微任务。 - 微任务:同理,也是一串被划分为微任务的js代码。包括
Promise中的resolve/rejectasync/awaitprocess.nextTick等(并没有归纳完)。同样,微任务也可以继续产生宏任务/微任务。
废话少说,赶紧聚个例子:
//先来个简单点的console.log("start");setTimeout(_ => console.log("setTimeout"), 0);console.log("end");// start// end// setTimout//解释不?算了不解释了// 第二个例子,还是简单点console.log("start");setTimeout(_ => console.log("setTimeout"), 0);new Promise(resolve => { console.log("new Promise"); resolve("promise then");}).then(res => console.log(res));console.log("end");// start// new Promise// end//promise then// setTimeout//解释不?还是解释哈嘛……/* 是弄个子的1.执行栈会首先去拿宏任务列表中的代码块来执行,此时只有script标签代码,所以就拿过来执行咯哟2.执行第一句,输出 start3.执行第二句,遇到了setTimeout,此时会将其回掉任务加入到下一轮的宏任务中4.new Promise中的代码直接执行(为什么直接执行,请看Promise相关知识),输出 new Promise,完了遇到了resolve代码,此时会将其回掉任务加入到下一轮微任务中5.输出 end,此时,本轮宏任务执行完毕,开始执行微任务6.由上可知,微任务中第一条(也仅此一条)是resolve的回掉,所以拿出来执行,输出 promise then7.微任务执行完了,再次执行宏任务,也从第一条开始,输出setTimeout8.done!!!*///第三个例子,不难,只是多添加了两位新客人而已console.log("start");setTimeout(_ => console.log("setTimeout"), 0);new Promise(resolve => { console.log("new Promise"); setTimeout(_ => console.log("new Promise setTimeout"), 0); resolve("promise then");}).then(res => console.log(res));async function asyncFunc1() { console.log("asyncFunc1 start"); await asyncFunc2(); console.log("asyncFunc1 end");}async function asyncFunc2() { console.log("asyncFunc2");}asyncFunc1();console.log("end");/* 先补充哈async/await的只是哈 */ /* 开始补充... */ /* 补充完毕 *///输出//start//new Promise//asyncFunc1 start//asyncFunc2//end//promise then//asyncFunc1 end//setTimeout//new Promise setTimeout/* 不用解释了,只需晓得 async/await 而且李杰了上一个例子,那就没问题了 */// 第四个例子console.log("start");setTimeout(function setTimeoutCallbackFunc1() {console.log("setTimeout")}, 0);new Promise(resolve => { console.log("new Promise"); setTimeout(function setTimeoutCallbackFunc2() {console.log("new Promise setTimeout")}, 0); resolve("promise then");}).then(function promiseThenCallbackFunc1(res) {console.log(res)});async function asyncFunc1() { console.log("asyncFunc1 start"); await asyncFunc2(); console.log("asyncFunc1 end");}async function asyncFunc2() { console.log("asyncFunc2"); return new Promise(resolve => { setTimeout(function setTimeoutCallbackFunc3() { console.log("asyncFunc2 promise"); resolve(); }, 0); })}asyncFunc1();console.log("end");//这又输出什么呢?这个可以说一哈,至于输出啥子,稍等哈,我复制到浏览器执行哈...// 执行完了,输出// start// new Promise// asyncFunc1 start// asyncFunc2// end// promise then// setTimeout// new Promise setTimeout// asyncFunc2 promise// asyncFunc1 end/* 终于打完了 */ /* 尽管我在浏览器中执行后照到打的,但是我能解释清楚 */ /* 开始装... */为了形象点,画图又不会,咋个搞呢?搞个都看得懂的
- macList = [] //宏任务队列
- micList = [] //微任务队列
- 比方:macList = [task1, task2, task3, task4, task5, …]
好了,开始装了…
- 首先,执行栈还是会先执行宏任务,那就去宏任务列表中取,此时的macList = [script],所以取出script执行,macList = []。
- 输出 start。
- 遇到setTimout,将回掉加入到宏任务列表中,macList = [setTimeoutCallbackFunc1]。
- 执行new Promise代码,输出 new Promise,而后遇到setTimeout,加入到红任务列表中,macList = [setTimeoutCallbackFunc1, setTimeoutCallbackFunc2],而后又遇到resolve,将其回掉加入到微任务列表,micList = [promiseThenCallbackFunc1]。
- (请先预备async/await知识)执行asyncFunc1函数,则输出 asyncFunc1 start,遇到 await asyncFunc2(),则先执行函数,输出asyncFunc2,而后返回了一个new Promise,new Promise中的代码回立马执行,遇到了setTimeout,加入到宏任务队列,macList = [setTimeoutCallbackFunc1, setTimeoutCallbackFunc2, setTimeoutCallbackFunc3],然后返回到asyncFunc1中,后边的代码会一律被封装到then中,直到asyncFunc2中resolve才会被执行。
- 第5点结束,asyncFunc1执行也就结束,而后输出 end。
- 至此,本轮宏任务结束,输出了 start, new Promise, asyncFunc1 start, asyncFunc2, end。开始执行微任务。
- 而后开始微任务列表挨个执行。此时micList = [promiseThenCallbackFunc1],取出promiseThenCallbackFunc1执行,输出 promise then。微任务队列执行完毕,再次执行宏任务。
- 此时宏任务列表macList = [setTimeoutCallbackFunc1, setTimeoutCallbackFunc2, setTimeoutCallbackFunc3]。挨个取出执行。
- 执行setTimeoutCallbackFunc1,输出 setTimout
- 执行setTimeoutCallbackFunc2,输出 new Promise setTimout
- 执行setTimeoutCallbackFunc3,输出 asyncFunc2 promise,但此时又遇到resolve,此时会将await asyncFunc2()后的代码当作回掉,加入到微任务列表中micList = [console.log(“asyncFunc1 end”)]。宏任务队列又执行完毕,又开始执行微任务。
- 此时微任务micList = [console.log(“asyncFunc1 end”)],取出执行,输出 asyncFunc1 end。此时一律执行完毕。
done!!!!
了解得不深,如有错误,赶紧指正,非常感谢!!!
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » JavaScript中的Event Loop小了解
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » JavaScript中的Event Loop小了解