Javascript运行机制(EventLoop)
本篇文章借鉴了阮一峰老师的再谈Event Loop www.ruanyifeng.com/blog/2014/1…
以及掘金大神的一篇博文 juejin.cn/post/684490…
一.关于Javascript的单线程
众所周知,javascript是单线程的。在某一时间,只能做一件事。那么,为什么javscript不能是多线程呢?
假设有两个线程,一个线程上添加了某个dom节点,另外一个线程上删除了dom节点。那么浏览器该以哪个线程为主呢。这就决定了javascript注定是单线程的。
二.事件循环
任务分为两种:同步任务和异步任务。
同步任务是指在主线程上执行的任务。只有当一个完成后,才能执行下一个任务。
异步任务是指在任务是指不进入主线程而进入任务队列的任务。
1.同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
2.当指定的事情完成时,Event Table会将这个函数移入Event Queue。
3.主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
4.上述过程会不断重复,也就是常说的Event Loop(事件循环)。
三.setTimeout和setInterval
setTimeout 延时执行,setInterval 间隔执行
setTimeout和setInterval只是将事件插入了任务队列,必须等到执行栈执行完,主线程才回去执行它指定的回调函数。
所以setTimeout(function() {}, 0)并不是马上执行。
setInterval并不一定每隔多久就会执行一次。对于执行顺序来说,setInterval会每隔指定的时间将注册的函数置入Event Queue,如果前面耗时太久,那么同样需要等待。
四.宏任务和微任务
宏任务包括script setTimeout setInterval
微任务包括process.nextTick,setImmediate,Promise.then()
不同类型的任务会进入对应的Event Queue
process.nextTick方法可以在当前执行栈的尾部---下一次主线程读取任务队列之前来触发回调函数,而setImmediate方法则是在当前任务队列的尾部添加事件。