• Event loop详解(包含Node端)


    Event loop事件循环,是一个执行模型。不同的浏览器以及Nodejs里的具体实现是不一样的。

     

    一,浏览器端:

     

    HTML5规范里有明确定义,简单的说:

     

    1,JS是单线程的,执行的时候在一条主栈上;

    2,当遇到异步代码时,会区分它是宏任务还是微任务;

    3,比如setTimeout和setInterval这类宏任务(macrotask),就会将他们放置到一个任务队列(也有称消息队列)中去,执行完成后,将callback推入到task中去等待执行;

    4,如果遇到了Promise和MutationObserver这类微任务(microtask),就会发到一个微任务队列中去(也称job),执行完成后,也是将callback推入等待执行;

    5,然后跳过他们继续执行后面的代码;当全局同步代码执行完成后,主线程清空了,这时候会把微任务队列推入主线程,依次执行清空,执行完毕后,将task中的第一个宏任务推入主线程执行;

    6,接着再去检查微任务job,如果有就全部清空,然后再推入一个宏任务;

    7,依次不断循环。。。

     

     

    其实关键点在于宏任务和微任务的处理方式,宏任务是每次事件循环只处理一个,而微任务是批量一次性处理完,微任务的处理时机是在每个宏任务之间的间隔中;

     

     

    二,node

     

    Node端是由libuv实现的,和浏览器实现方式大致相同,但是会有少许差异。

    Node中的宏任务队列分为6个阶段(依次为):

     

    1,timers:用来执行setTimeout和setInterval到期后的callback

    2,I/O callbacks:上一轮循环中有少数的I/O callbacks会被延迟到这一轮的这个阶段执行

    3,idle,prepare:这个阶段仅供内部使用,无需了解

    4,poll:这个阶段是最重要的阶段,执行I/O callback,并且在适当的时候会在这个阶段进行阻塞

    5,check:这个阶段是执行setImmediate的callback

    6,close callbacks:执行close事件的callback,比如 socket.on(‘close’, func)

     

    在浏览器端,可以理解为只有一个宏任务队列,所有的宏任务都在里面,但是在node端,需要区分开,不同类型的宏任务放在不同的队列里,执行时机和顺序也是有规范的,并不是先进先出。

     

    而微任务队列也有两个(按顺序依次):

    NextTick Queue:放置process.nextTick的callback

    Other Microtask:放置Promise等其它的微任务

    这两个也是有先后顺序的

     

    那宏任务和微任务的执行时机呢?

     

    这里我们要区分一下Node版本:@11以前,和@11以后

     

    11以前:

    按顺序依次取出微任务队列中所有的微任务, 全部执行,  接着取出一个阶段中的所有的callback,比如先是timers,全部执行完后(仅仅是timers的callback),再去执行微任务队列,然后依次下去。

     

    区别于浏览器的是,Nodejs中微任务的执行时机是在每个宏任务队列阶段之间,而且是有顺序的,而宏任务也不是每次只取一个,而是取一类的队列,然后全部执行;

     

    11以后:

    和浏览器保持一致,也是一个一个的取,而不是一次性取一个队列的宏任务了,其它不变。

  • 相关阅读:
    MVC.Net:Razor指定模板
    Intellij Idea 13:导入openfire源代码
    SharePoint 2013:解决爬网出错的问题
    MySQL:解决MySQL无法启动的问题
    SharePoint 2013:解决添加域名后每次都需要登录的问题
    Android 动画
    android:persistent属性
    ubuntu 安装 open in teminal
    利用python建表
    flask request
  • 原文地址:https://www.cnblogs.com/yanchenyu/p/13601387.html
Copyright © 2020-2023  润新知