EventLoop之Node事件循环

本文深入探讨了JavaScript中的事件循环机制,解释了它是如何作为浏览器和Node.js中JavaScript与系统调用间的桥梁。同时阐述了进程与线程的概念,指出进程是线程的容器。此外,分析了Node.js的架构,特别是libuv在事件循环中的作用。文章还详细介绍了Node.js事件循环的各个阶段,并给出了一个具体的面试题案例来说明执行顺序。
摘要由CSDN通过智能技术生成

一、什么是事件循环?

通俗来说就是我们所编写的Javascript和浏览器或者Node之间的一个桥梁。

浏览器的事件循环是我们编写的Javascript代码和浏览器API调用(setTimeout/AJAX/监听事件)的一个桥梁,桥梁之间他们通过回调函数进行通信。

Node的事件循环是一个我们编写的JavaScript代码的系统调用(file system/network等)之间的一个桥梁,桥梁之间他们通过回调函数进行通信。
在这里插入图片描述

连接两个东西之间的桥梁。

二、进程与线程

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

  • 进程(process):计算机已经运行的程序
  • 线程(thread):操作系统能够运行运算调度的最小单元

听起来很抽象,直观一点:

  • 进程:启动一个应用程序,就会默认启动一个进程(也有可能是多个)
  • 线程:每一个进程中,都会启动一个线程用来执行程序中的代码,这个线程被称为主线程;

所以我们也可以说,进程是线程的容器

抽象表达:
工厂 => 车间 => 工人(多人)
操作系统 => 进程 => 线程

三、Node架构分析

浏览器中的EventLoop是根据HTML5定义的规范来实现的,不同的浏览器可能会有不同的实现,而Node中是由libuv实现的。

我们来看在很早就给大家展示的Node架构图:

  • 我们会发现libuv中主要维护了一个EventLoop和worker threads(线程池);
  • EventLoop负责调用系统的一些其他操作:文件的IO、Network、child-processes等

libuv是一个多平台的专注于异步IO的库,它最初是为Node开发的,但是现在也被使用到Luvit、Julia、pyuv等其
他地方;

在这里插入图片描述
阶段概述

  • 定时器:本阶段执行已经被 setTimeout() 和 setInterval() 的调度回调函数。
  • 待定回调:执行延迟到下一个循环迭代的 I/O 回调。
  • idle, prepare:仅系统内部使用。
  • 轮询:检索新的 I/O 事件;执行与 I/O 相关的回调(几乎所有情况下,除了关闭的回调函数,那些由计时器和 setImmediate() 调度的之外),其余情况 node 将在适当的时候在此阻塞。
  • 检测:setImmediate() 回调函数在这里执行。
  • 关闭的回调函数:一些关闭的回调函数,如:socket.on(‘close’, …)。

Node的事件循环队列:

  • ticks队列
  • 其他微任务队列
  • timers队列:setTimeout
  • I/O队列
  • setImmediate 队列
  • close队列

面试题:

async function async1() {
  console.log('async1 start');
  await async2()
  console.log('async1 end');
}

async function async2() {
  console.log('async2');
}

console.log('script start');

setTimeout(() => {
  console.log('setTimeout0');
}, 0);

setTimeout(() => {
  console.log('setTimeout2');
}, 300);

setImmediate(() => console.log('setImmediate'))

process.nextTick(() => console.log('nextTick1'))

async1()

process.nextTick(() => console.log('nextTick2'))

new Promise((resolve) => {
  console.log('promise1');
  resolve()
  console.log('promise2');
}).then(() => {
  console.log('promise3');
})
console.log('script end');

解析:
在这里插入图片描述
结果:

/**
 * script start
 * async1 start
 * async2
 * promise1
 * promise2
 * script end
 * nextTick1
 * nextTick2
 * async1 end
 * promise3
 * setTimeout0
 * setImmediate
 * setTimeout2
 */
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

优雅哥cc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值