事件循环的详解

一、进程和线程的概念 

线程和进程是操作系统中的两个概念 :

  • 进程(process):计算机已经运行的程序,是操作系统管理程序的一种方式;
  • 线程(thread):操作系统能够运行运算调度的最小单位,通常情况下它被包含在进程中;

操作系统是如何做到同时让多个进程同时工作:

  • 这是因为CPU的运算速度非常快,它可以快速的在多个进程之间迅速的切换;
  • 当我们进程中的线程获取到时间片时,就可以快速执行我们编写的代码;
  • 对于用户来说是感受不到这种快速的切换的;

浏览器

  • 目前多数的浏览器其实都是多进程的,当我们打开一个tab页面时就会开启一个新的进程,这是为了防止一个页 面卡死而造成所有页面无法响应,整个浏览器需要强制退出;

  • 每个进程中又有很多的线程,其中包括执行JavaScript代码的线程;

浏览器中的JavaScript线程

JavaScript是单线程的 ,它也有自己的容器进程:浏览器或者Node。 JavaScript的代码执行是在一个单独的线程中执行的:

  • 这就意味着JavaScript的代码,在同一个时刻只能做一件事;

  • 如果这件事是非常耗时的,就意味着当前的线程就会被阻塞;

如果有耗时操作,实际上并不是由JavaScript线程在执行的。浏览器的每个进程是多线程的,那么其他线程可以来完成这个耗时的操作。比如网络请求、定时器,我们只需要在特性的时候执行应该有的回调即可 。

二、浏览器的事件循环

  • 有个js线程,当执行到一些代码是执行异步操作的时候,他会将异步操作的代码交由浏览器的其他线程来管理这些代码

  • 其他线程,比如遇到一个setTimeout函数的回调函数代码,并1s后运行,那么浏览器的其他线程会开始计时操作,当到达时间,会将这部分代码交由事件队列处理

  • 事件队列,js线程会从事件队列中一次取出代码执行

  • 这样会构成一个闭环,这就称为浏览器的事件循环

三、浏览器宏任务和微任务

事件循环中并非只维护着一个队列,事实上是有两个队列:

  • 宏任务队列(macrotask queue):ajax、setTimeout、setInterval、DOM监听、UI Rendering等

  • 微任务队列(microtask queue):Promise的then回调、 Mutation Observer API、queueMicrotask()等

两个队列的优先级 :

  • main script中的代码优先执行(编写的顶层script代码);

  • 在执行任何一个宏任务之前(不是队列,是一个宏任务),都会先查看微任务队列中是否有任务需要执行 。就是宏任务执行之前,必须保证微任务队列是空的,如果不为空,那么就优先执行微任务队列中的任务(回调)

五、Node环境的事件循环

一次完整的事件循环Tick分成很多个阶段:

  • 定时器(Timers):本阶段执行已经被 setTimeout() 和 setInterval() 的调度回调函数。

  • 待定回调(Pending Callback):对某些系统操作(如TCP错误类型)执行回调,比如TCP连接时接收到 ECONNREFUSED。

  • idle, prepare:仅系统内部使用。

  • 轮询(Poll):检索新的 I/O 事件;执行与 I/O 相关的回调;

  • 检测(check):setImmediate() 回调函数在这里执行。

  • 关闭的回调函数:一些关闭的回调函数,如:socket.on('close', ...)。

六、Node的宏任务和微任务

Node的事件循环更复杂,它也分为微任务和宏任务:

  • 宏任务(macrotask):setTimeout、setInterval、IO事件、setImmediate、close事件;

  • 微任务(microtask):Promise的then回调、process.nextTick、queueMicrotask;

Node中的事件循环不只是 微任务队列和 宏任务队列:

微任务队列:

  • next tick queue:process.nextTick;

  • other queue:Promise的then回调、queueMicrotask;

宏任务队列:

  • timer queue:setTimeout、setInterval;

  • poll queue:IO事件;

  • check queue:setImmediate;

  • close queue:close事件;

七、Node事件循环的顺序

在每一次事件循环的tick中,会按照如下顺序来执行代码:

  • next tick microtask queue;

  • other microtask queue;

  • timer queue;

  • poll queue;

  • check queue;

  • close queue;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值