什么是eventloop(事件循环)?

上篇文章提到一个for循环下定时器闭包的demo,为什么在循环结束之前,定时器都不会运行呢

这就要提到eventloop(事件循环)了。

Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。

聊事件循环前先说一下堆、栈、队列吧

堆(Heap)

堆是一种数据结构,是利用完全二叉树维护的一组数据,堆分为两种,一种为最大堆,一种为最小堆,将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

堆是线性数据结构,相当于一维数组,有唯一后继。

栈(Stack)

栈在计算机科学中是限定仅在表尾进行插入或删除操作的线性表。栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据。

栈是只能在某一端插入和删除的特殊线性表。

队列(Queue)

特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。

进行插入操作的端称为队尾,进行删除操作的端称为队头。 队列中没有元素时,称为空队列。

队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out

而事件循环就是指在javascript是单线程的模式下,如果要有异步任务那么需要如何进行任务调度

事件循环中把任务分成了两大类,同步任务和异步任务,其中异步任务又分宏任务微任务

其中宏任务包括:

1.script(整体代码)

2.settimeout/setinterval

3.I/O操作

4.UI render

等等

微任务有:

1.Promise的一系列方法(请注意promise本身是同步的哦!)

2.MutationObserver

等等

同步任务会在调用栈中按照顺序等待主线程依次执行,异步任务会在异步任务有了结果后,将注册的回调函数放入任务队列中等待主线程空闲的时候(调用栈被清空),被读取到栈内等待主线程的执行。异步任务不在主线程中时,要在任务队列中等待调用。

执行栈在执行完同步任务后,查看执行栈是否为空,如果执行栈为空,就会去检查微任务(microTask)队列是否为空,如果不为空的话,会按照先入先出的规则全部执行完微任务(microTask)后,设置微任务(microTask)队列为null,然后再执行宏任务,如此循环。

举个例子来看

以下代码的输出是

134652

1346为同步任务首先执行 5是异步任务中的微任务 6是异步任务中的宏任务

所以我们可以得出一个结论 eventloop的执行顺序是:同步任务>微任务>宏任务

了解完eventloop以后,介绍一下为什么说 event-loop 在 IO 密集型场景中比线程模型更高效?

因为它用了异步的API,从而节省了线程的开销,原来几十个线程才能搞的事,通过异步api之后,几个线程就能做了。io bound的应用,如果采用eventloop模型,性能提升几十倍甚至更多,看具体io的密集程度,io越多,性能提升越明显,注意这里是两个数量级以上的提升,这个意义十分重大,因为eventloop使用的是异步api,而异步api在调用的时候,会马上返回,所以eventloop不会被blocked,而传统的同步api会block住调用线程,导致线程空转等待,一个线程的stack怎么说也有1m,多来几个就耗尽内存了,同时线程多也增加了cpu调度的负担

才疏学浅,欢迎指正!

 

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值