EventLoop的深入研究

可以先了解一下这个demo,猜一下他的输入顺序

new Promise( resolve=>{
	resolve(1);
	Promise.resolve().then(()=>{console.log(2)});
	console.log(4);
}).then(t=>{
	console.log(t)
});
console.log(3)

什么是EventLoop ?

为了协调事件、用户交互、脚本、UI渲染和网络请求等行为,防止线程阻塞,EventLoop的方案就应运而生。
EventLoop包含两类:
1、基于Browsing Context
2、基于Worker
两者是独立的,也就是说每个javascript运行的“线程环境”都有一个独立的EventLoop,每个WebWorker也有一个独立的EventLoop

任务队列

事件循环是通过任务队列的机制进行协调的,一个EventLoop可以有一个或者多个任务队列,一个任务队列便是一个有序的任务队列的集合,每个任务都有一个任务源,源自同一个任务源的task必须放在同一个任务队列,不同源的则被添加到不同的队列。在事件循环中,每进行一次循环操作成为tick,每一次tick的任务处理模型如下:

1、把oldestTask标记为oldest Task,UA可以选择任意任务队列,如果没有选择跳到Microtasks微任务处理
2、将当前运行的任务设置为oldestTask
3、运行oldestTask
4、将事件循环的当前运行任务,置为null
5、从任务队列中移除oldestTask
6、检查是否存在microTasks,如果存在则不停的执行,直至清空microTasks queue
7、更新render
(判断Document在此时间点渲染是否会“获益”,浏览器只需要保证60Hz的刷新频率即可,若>EventLoop频率过高,即使渲染了浏览器也无法及时展示,所以并不是每一轮EventLoop都会执行>UI render
1、执行渲染所需要的工作,如触发resize、scroll、建立媒体查询、运行css动画等
2、执行Animation Frame Callbacks
3、执行IntersectionObserver callback
4、渲染UI)
8、主线程重复执行上述步骤

异步任务可以分为macrotask和microtask,不同的API注册的异步任务会依次进入自身相应的队列中,然后等待EventLoop将它们依次压入执行栈中执行。

macroTask 又称之为task
microTask 又称之为job
macroTask包含:script整体代码、setInterval、setTimeout、I/O、UI交互事件、postMessage、MessageChannel、setImmediate(nodejs环境)
microTask包含:Promise.then、MutationObserver、process.nextTick(nodejs环境)
在node环境当中会优先清空nextTick queue,再清空other queue,常见的如Promise
此外timers(setTimeout、setInterval)会优先与setImmediate执行,因为前者在timer阶段执行,后者在check阶段执行。

Nodejs大致的事件虚汗执行顺序如下

Created with Raphaël 2.3.0 开始 Timers阶段 IO callbacks阶段 idle,prepare阶段 poll阶段 <--------incoming:connection,data,etc check close callbacks yes
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值