基于真实案例浅谈事件循环EventLoop
前情提要
为什么说是浅谈呢?因为EventLoop的牵扯到的情况特别复杂也特别的庞大,一句两句讲不清楚,可能讲着讲着把自己就给讲糊涂了。所以我们就由表及里,以结果为导向看看事件循环的运行机制。
什么是事件循环?
事件循环的本质是在浏览器或者nodejs的环境中,运行时对js脚本的调度方式。
首先我们先了解下js为什么会有事件循环机制?
我们都知道JavaScript是单线程的。所谓单线程,就可以理解为一个人的心一段时间只能放下一个人,分开了才能去存放另一个人,无法一心二用。但是如果按照这种情况走下去,假如代码块中遇到了计时器5秒甚至50秒后触发,那么整个程序都会因为还没有到程序的执行时间而停滞不前,进而进入假死状态。这种情况自然是我们所不希望看到的,我们希望遇到此类需要等待的代码时跳过去,先执行不需要等待的代码,最后再来执行这些需要等待的代码。于是JavaScript就引入了事件循环机制,来模拟多线程的效果。
而实现这种效果的方式就是事件循环EventLoop机制
其次是如何实现这种机制
同步任务为一个任务执行栈(栈的规则是先进后出)
异步任务是一个消息队列(消息队列的规则是先进先出)。
同时还有浏览器提供的webApi,可以理解为浏览器自己提供的api会在另一个线程处理,处理完成后会自动塞到js的消息队列里。
消息队列又分为宏任务队列和微任务队列。
该机制将js分为同步任务和异步任务。
浏览器提供的api是宏任务:setTimeout, setInterval,setImmediate, ajax, nextTick, requestAnimationFrame, UI render...
js引擎提供的是微任务:promise, async/await...
script中的js代码也是宏任务
执行优先级
同步任务 => nextTick => 异步任务 => setImmediate
从代码执行验证上述理论
注意事项:
process.nextTick只在node环境中生效。
总结
在浏览器中事件循环除了js的处理还有ui线程的处理。每走完一轮js的便会走一遍ui的处理。以此往复形成事件循环,但ui线程那块暂时想不到演示示例,所以目前只演示了js这一块。