b.浅谈js的事件轮询(宏任务、微任务)

事件轮询概念


  事件轮询(Event Loop)是一个很重要的概念,指的是计算机系统的一种运行机制。JavaScript语言就是采用的这种机制,来解决单线程运行带来的一些问题。

想要理解EventLoop,就要从程序的运行模式讲起。运行以后的程序叫做"进程"(process),一般情况下,一个进程一次只能执行一个任务。

如果有很多任务需要执行,不外乎三种解决方法。

(1)排队。因为一个进程一次只能执行一个任务,只好等前面的任务执行完了,再执行后面的任务。

(2)新建进程。使用fork命令,为每个任务新建一个进程。

(3)新建线程。因为进程太耗费资源,所以如今的程序往往允许一个进程包含多个线程,由线程去完成任务。

 以JavaScript语言为例,它是一种单线程语言,所有任务都在一个线程下完成,即采用上面的第一种方法,一旦遇到大量任务或者遇到一个耗时的任务,网页就会出现假死的状态,因为JavaScript停不下来,也就无法响应用户的行为。

很多人问为什么JavaScript不能实现多线程呢,例如如果是多线程的话,多个线程去操作同一个Dom元素,那么结果就造成一个很严重的问题,所以js是单线程的,但如果完全由上至下的执行代码,前面的代码没有执行完,后面必须要等待当前执行完毕,这样的效率是非常低的,所以有了异步的概念,JavaScript 的主线程是单线程的,但是也有其他的线程去帮我们实现异步操作,比如Ajax 线程、定时器线程、事件线程。


JavaScript的任务


1.宏任务

宏任务包括整体代码script,setTimeout,setInterval, I/O,UI Rendering

2.微任务

微任务包括Promise.then(非new Promise),process.nextTick

不同类型的任务会进入不同的Event Queue,有宏任务的队列和微任务的队列。

我们来看下面这道题就可以清晰了解宏、微任务区别:

setTimeout(() => { console.log( 'd' ); }, 0);

new Promise(resolve=>{

console.log('a'); 

for(let i =0;i<10000;i++){ i == 9999 && resolve(); } console.log( 'b' ) }).then(()=>{ console.log( 'e' ) })  

 console.log( 'c' ) 

答案是 a b c e d,让我们来看看执行流程:

图1

通过图片我们可以看出,进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务

所以上面那道题是宏任务会先将延时器放到事件队列中,等待下一轮执行宏任务才会执行延时器,继续找宏任务a b c ,直到没有宏任务就会执行微任务,也就是e ,微任务也执行完毕,就会开启新一轮的执行宏任务,所以最后打印d

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容