最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 关于Event loop的问题

    正文概述 掘金(TuuOrange_)   2021-03-29   438

    Event loop即事件循环,就是指浏览器或者Node(JS运行的环境)用来解决JS单线程运行阻塞的问题的一种机制。 关于Event loop,它分为MacroTask(宏任务)和MicroTask(微任务)。

    首先,我们来谈一下JS的单线程运行。

    何为单线程?

    当一个程序运行时,就可以视为一个进程。运行中的程序和程序所需要的资源都是进程,而一个进程一般是由多个线程组成的。
    多个线程意味着有多个不同的执行流执行不同的任务。多线程运行时,不是其他线程等待一个执行完,而是各自运行。但是,同时多线程运行时占用的内存偏多,且会出现共享资源争夺的情况,容易造成很多麻烦的Bug。
    而单线程是按顺序执行,不需要占用过多的内存资源。

    那么为何JS会是单线程呢?

    JS从诞生之初就是单线程。阮一峰老师在他的博客中提到:大概是因为不想让浏览器变得像多线程那样复杂,因为多线程需要共享资源、且有可能修改彼此的运行结果,对于一个网络脚本语言来说,太过于复杂了,还是单线程比较适合JS。而Event loop就是用来解决JS单线程运行阻塞、等待时间过长的一种机制。

    宏任务(Macro Task)

    宏任务是由宿主,也就是JS运行的环境(浏览器和Node),发起的。
    script代码、setTimeout、setInterval、setImmediate、I/O(Node.js)、UI rending/UI事件都是宏任务的具体事件
    在代码中,一般后运行,并会触发新一轮的Tick。

    微任务(Micro Task)

    微任务是由JS引擎发起的。
    Promise、MutationObserve、Object.observe(已废弃;Proxy对象替代)、Process.nextTick(Node.js独有)
    在代码中,一般会先行运行,并不会触发新一轮的Tick。

    浏览器与Event loop

    程序中,会设置两个线程,一个是负责程序本身的运行,为“主线程”(main thread);另一个则负责主线程与I/O操作之间的通信,即调用栈(执行栈)call-stack,所有的任务都会放在栈中等待被主线程执行。

    在主线程中,最先执行的任务会存储在任务队列中放入执行栈中执行,当任务队列为空时,则会从微任务队列中选择任务放入到任务队列中,直至任务都被完成。执行进入Micro的检查点时,会先设置Micro的检查点为true,当Micro不为空时,选择一个任务task进入队列中,并将其设置为已选择的microtask,运行microtask,将已经执行完的microtask设置为null,清理indexDB事务,重新设置Micro检查点为false,更新界面。

    浏览器中Event loop会先检查执行栈,如果执行栈为空,则去执行宏任务,宏任务执行完成之后,会去检查微任务队列,如果不为空,则依次执行微任务,直至微任务执行完成之后再去执行宏任务。

    Node.js与Event loop

    Node中Event loop中的libuv实现的。

    什么是libuv?

    libuv是一个高性能、事件驱动的异步I/O库。libuv封装了不同平台底层对于异步I/O模型的实现。
    现阶段的Node提供libuv作为封装层,使Node具备了跨平台的能力。

    Node的Event loop被分为6个阶段:

    • timers:执行setTimeout和setInterval中时间到期满足(达到最快定时器的阈值 - 由于调度会产生一些延时)的callback。

    • pending callback:某些系统操作的回调(例如:TCP错误类型)

    • poll:

      1. 执行I/O回调
      2. 处理轮询队列中的事件

      如果poll队列不为空,则会循环遍历执行它们的callback队列;如果有setImmediate()需要回调执行,则停止poll阶段进入check阶段执行回调;如果没有setImmediate(),poll将callback放入队列中执行;如果poll为空,则会判断timer是否超时,如果有的话则回到timer。

    • check:如果poll已完成或者闲置并且setImmediate()已排队,则立即执行check阶段。

    • close callback:执行close事件中的callback。

    setImmediate()与定时器

    setImmediate()在poll阶段执行完成或者闲置之后立即执行,在check阶段
    定时器在timer阶段执行

    Process.nectTick()

    process.nextTick()从技术上讲,并不是事件循环的一部分。在每个阶段完成之后,如果存在nextTick就会清空队列中所有的callback立即执行nextTick。

    浏览器的Event loop与Node中的loop的区别

    Node端的事件循环,MicroTask在事件循环的各个阶段之间执行 浏览器中的时间循环,MicroTask在事件循环的MacroTask执行完之后再执行


    起源地下载网 » 关于Event loop的问题

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元