javascript-eventLoop

理解

 

 

js是单线程语言,主要是由于js会操作dom.假设js是多线程,一个线程执行打开弹出框操作,另一个线程执行关闭弹出框操作,两个线程同时执行(线程可以并发执行),这就造成了问题,浏览器不知道应该执行哪一个操作.这就是js为什么要设置为单线程的原因.但是单线程会导致一个问题:任务排队.如果前一个任务执行时间很长,后面的所有任务都要等待前一个任务完成,造成了非常差的用户体验,也没有充分利用cpu.为了解决排队的问题,诞生了异步任务.

异步任务在执行时,会新开一个线程去执行,但是异步任务执行后的回调函数并不是立即执行,而是放到任务队列中,等到主线程中的任务执行完成后,才会去任务队列中寻找可以执行的回调函数

关于上图的理解:js在执行时首先遇到script,script是宏任物,宏任物内有同步任务和异步任务,js从上到下遍历一遍script,当遇到同步任务放到主线程,遇到异步任务时放到event table中,在event table阶段会完成回调函数的注册.这个阶段有2个线程,一个主线程去执行同步任务.另一个线程就去执行异步任务(evnet table),当异步事件运行有了结果后,会注册一个事件放到的任务队列中,任务队列分为宏任物和微任务,先去执行微任务队列中的所有微任务.script中主线程内容执行完后,就去微任务队列执行所有微任务事件对应的回调函数,进入新的“执行栈”开始执行,再去执行宏任物队列中的宏任务事件的回调函数,如果当前执行宏任物中有微任务,那么该宏任物执行完后就回去执行微任务,再执行宏任物,以此循环,就是js的事件循环.

宏任物

setTimeout是宏任务也属于异步任务,在设置第二个参数为0时,并不是立即执行,而是在同步任务和当前任务队列中的现有事件执行完后立即执行;第二个参数是指定多少时间后把事件放入event queue中;如果当前事件执行需要300ms,而set设置的时间是100ms,那么setTimeout(fn,100)和setTimeout(fn,0)也没什么区别

 

 

 

微任务

promise是一个特殊的,再promise内部的方法会立即执行,但是promise.then内部的方法属于微任务

 

最后

一个优先级同步代码(宏任务) > Promise(微任务)> setTimeout(fn)、setInterval(fn)(没有第二个参数时,第二个参数默认为0)> setTimeout(fn, time)、setInterval(fn, time),其中time>0

 

posted @ 2019-08-06 20:40  大笛子  阅读(111)  评论(0编辑  收藏  举报