事件循环在浏览器环境下我们的js有一套自己的事件循环,同样在node环境下也有一套类似的事件循环。
浏览器环境事件循环首先,我们先来回顾一下在浏览器的事件循环: 总结来说: 首先会运行主线程的同步代码,每一行同步代码都会被压入执行栈,每一行异步代码会压入异步API中(如:定时器线程、ajax线程等;),在执行栈没有要执行的代码时,也就是我们当前主线程没有同步代码了,任务队列会从我们的异步任务微任务队列中取一个微任务放到我们的任务队列中进行执行,将它的回调函数进而再次放到执行栈中进行执行,当微任务队列为空时,会在宏任务中取异步任务加到任务队列,进而压入执行栈,执行回调函数,然后继续在该宏任务中查找同步、异步任务,一次循环,完成了一个事件循环(事件轮询)
浏览器环境下的例子: 例子: console.log("1"); setTimeout(() => { console.log("setTimeout"); }, 1); new Promise((res, rej) => { console.log("Promise"); res('PromiseRes') }).then(val => { console.log(val); }) console.log("2"); 分析: 首先执行栈找到第一行的同步代码,直接扔到执行栈中执行,打印1,随后为定时器setTimeout,为异步任务,将代码放到异步对列中等待执行,随后执行promise中的代码,我们要清楚promise是同步执行,它的回调是异步执行,所有打印Promise,将res(‘PromiseRes')放到异步对列中等待执行,这个时候又遇到了同步代码,打印2,当前主线程的同步代码全部执行完毕,并且执行栈中没有要执行的同步代码,这个时候webApi会从异步队列中去微任务队列中的第一个,加入到事件队列执行,将返回的回调函数压入到执行栈中执行,打印PromiseRes,随后微任务执行完毕,已经没有微任务,现在就需要从宏任务队列中取宏任务定时器,加入到任务队列中,将回调函数压入到执行栈中执行,打印setTimeout。
node环境事件循环在node中事件循环主要分为六个阶段来实现: 外部数据输入 如何基于js管理大文件上传及断点续传详析 带你了解JavaScript的运行原理
|