js事件环

1.1 概括

这篇文章主要讲解下前端javascript和node中的事件循环机制,原因如下:

  • 大家都知道,浏览器的渲染引擎主要有ui线程和js线程两部分,而由于js的执行可能会休改ui线程的渲染。所以二者是互斥的。即当ui线程在执行时,会阻塞js线程的运行。反之亦然。
  • js的主线程是单线程的,这是为了不会产生多个js同时对DOM进行修改而导致的页面混乱。但为什么说js的主线程是单线程呢。因为js为了提升性能。js又供了事件回调、定时任务、ajax请求等用于跳出主线程任务。

1.2 堆、栈、队列

在讲解事件环机制前,先和大家明确几个基础概念

  1. 堆(heap):存放js中的对象,向外暴露其内存地址。不会自动清除(其引用为0时,清除)
  2. 栈(stack):先进后出的数据模式,js的主调用流程的存储结构,调用结束即清除
  3. 队列(queue):先进先出的存储模式,js中宏任务(macro-task)及微任务(micro-task)的存储结构

1.3 宏任务和微任务

  • 宏任务(micro-task)主要是:setTimeout、setInterval、Promise的构造函数是同步的、setImmediate、I/O、UIrendering
  • 微任务(macro-task)主要是:Promise的回调(then)、process.nextTick

2.1 javascript中的事件环

根据上图,解析:

  1. js文本在进行解析后,会将文件中的任务进行分配为:主线程队列,微任务队列和宏任务队列
  2. 主线程队列会依次从队列中pop到调用栈中执行,在执行中如果内部包含微任务/宏任务则会再次推入微任务队列/宏任务队列
  3. 主任务队列执行完毕后,会查看微任务队列&宏任务队列中是否有需要执行的任务,拥有的话,将其推入到主任务队列。
  4. 循环上述操作,形成js的执行环

2.2 客户端js时间环特点

js在调用栈中执行宏任务时,如果内部含有微任务,则这个微任务不会被推入微任务队列中,直接在宏任务执行时直接执行

2.3 node中的事件环

根据上图,Node.js的运行机制如下:

  1. 写的JavaScript脚本会交给V8引擎解析
  2. 解析后的代码,调用Node API,Node会交给Libuv库处理
  3. Libuv库将不同的任务分配给不同的线程,形成一个Event Loop(事件循环),以异步的方式将任务的执行结果返回给V8引擎
  4. V8引擎再将结果返回给用户

node的宏任务中也拥有自己的先后顺序 :如下图

上图解析:

  1. 根据上图可知,node中的宏任务也是分为几个模块的,如timers,poll,check等
  2. 主队列任务执行时,如果内部有相应宏任务,则会根据宏任务类型放置到不同模块中。当主任务队列执行完毕后,宏任务列表会依据模块顺序(从上到下)将可立即执行的宏任务推至主任务队列中,依次执行

转载于:https://juejin.im/post/5ab88b736fb9a028bd4c4c3f

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值