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以后:

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

Event loop详解(包含Node端)的更多相关文章

  1. JavaScript:event loop详解

    之前已经有两篇随笔提到了event loop,一篇是事件机制,一篇是tasks和microtasks,但是里面的event loop都是文字描述,很难说细,逻辑也只是简单的提了一遍.其实之前也是通过阮 ...

  2. Event Loop详解

    1.进程,单线程与多线 进程: 运行的程序就是一个进程,比如你正在运行的浏览器,它会有一个进程. 线程: 程序中独立运行的代码段. 一个进程由单个或多个线程组成,线程是负责执行代码的. 2.单线程与多 ...

  3. JS中的event 对象详解

    JS中的event 对象详解   JS的event对象 Event属性和方法:1. type:事件的类型,如onlick中的click:2. srcElement/target:事件源,就是发生事件的 ...

  4. (转)javascript中event对象详解

    原文:http://jiajiale.iteye.com/blog/195906 javascript中event对象详解          博客分类: javaScript JavaScriptCS ...

  5. Objective-C之run loop详解

    Objective-C之run loop详解 做了一年多的IOS开发,对IOS和Objective-C深层次的了解还十分有限,大多还停留在会用API的级别,这是件挺可悲的事情.想学好一门语言还是需要深 ...

  6. WebSocket安卓客户端实现详解(三)–服务端主动通知

    WebSocket安卓客户端实现详解(三)–服务端主动通知 本篇依旧是接着上一篇继续扩展,还没看过之前博客的小伙伴,这里附上前几篇地址 WebSocket安卓客户端实现详解(一)–连接建立与重连 We ...

  7. EditText使用详解-包含很多教程上看不到的功能演示

    写道 标题有点大,说是详解,其实就是对EditText的一些常用功能的介绍,包括密码框,电话框,空白提示文字等等的讲解,尽量的介绍详细一点,也就是所谓的详解了..呵呵 广告一下我的应用“我团”,最新1 ...

  8. 详解 HTTPS 移动端对称加密套件优

    近几年,Google.Baidu.Facebook 等互联网巨头大力推行 HTTPS,国内外的大型互联网公司很多也都已启用全站 HTTPS. Google 也推出了针对移动端优化的新型加密套件 Cha ...

  9. Zabbix配置文件详解之服务端zabbix_server

    zabbix作为运维邻域不可缺少的一员,它的各种文档可是数不胜数啊,但是关于配置文件的解释与说明就有点少.这里列出zabbix配置文件篇之zabbix_server. Zabbix Server端配置 ...

随机推荐

  1. MYSQL-MGR架构配置

    MGR安装:机器列表:pc-s4 s4 --2pc-s3 s3 --1pc-s1 s1 --1pc-s2 s2 --1 1,为初始化搭建,2,为后续添加 对1 三个数据库先进行初始化========= ...

  2. GLIBC_2.18 not found 之类的问题解决办法

    先到 /usr/lib64 下 ll libstdc++* 会发现 libstdc++.so.6 指向了一个新的.比如我这里之前指向6.0.22这个版本,报错 此时只要重新建立软连接 将软连接指向旧的 ...

  3. python的单下划线和双下划线

    python 类中的单下划线开头的变量表示:该方法为类的私有方法,原则上外部不能访问,但是用._XX是可以访问到的 双下划线开头则是强制外部不能直接访问的用.__XX是访问不到的,它内部其实是将变量名 ...

  4. Spring bean自定义命名策略(注解实现)

    我们都知道项目后台开发是从 控制层——业务层——mybatis层,@Controller.@Service.@Mapper...等等注解可以将对象自动加载到bean容器中,还能实现相应的功能,使用起来 ...

  5. python获取系统内存占用信息的实例方法

    psutil是一个跨平台库(http://code.google.com/p/psutil/),能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等)信息.它主要应用于系统监控, ...

  6. Docker初探之常用命令

    在正式使用Docker之前,我们先来熟悉下Docker中常用的命令,因为对Docker的操作就如同操作Linux一样,大部分操作通过命令完成. 一.登录 为什么要使用登录? 因为我们使用Docker, ...

  7. C#LeetCode刷题之#237-删除链表中的节点(Delete Node in a Linked List)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3832 访问. 请编写一个函数,使其可以删除某个链表中给定的(非末 ...

  8. C#图解教程(第四版)—01—类型,存储,变量

    3.1 如何广泛的描述C#程序 可以说C程序是一组函数和数据类型,C++程序是一组函数和类,然而C#程序是一组类型声明 3.2 类型 可以把类型想象成一个用来创建数据结构的模板,模板本身并不是数据结构 ...

  9. 数据库之Oracle优化技巧(一)

    数据库之Oracle优化技巧(一) 1.where子句中的连接顺序 在Oracle数据库中,where子句的执行顺序是自下而上进行解析,根据这个原理,表之间的连接必须写在其他where条件之前,那些可 ...

  10. 2w字 + 40张图带你参透并发编程!

    并发历史 在计算机最早期的时候,没有操作系统,执行程序只需要一种方式,那就是从头到尾依次执行.任何资源都会为这个程序服务,在计算机使用某些资源时,其他资源就会空闲,就会存在 浪费资源 的情况. 这里说 ...