📜  异步函数和 Node.js 事件循环(1)

📅  最后修改于: 2023-12-03 14:54:11.130000             🧑  作者: Mango

异步函数和 Node.js 事件循环

什么是异步函数?

异步函数是指在函数执行期间不会阻塞程序执行的函数。这些函数通常使用回调函数(callback)、Promise 或 async/await 语法来进行异步处理。

异步函数通常用于处理网络请求、文件读写、数据库查询等耗时操作,这些操作可能会阻塞程序执行,导致程序性能下降甚至崩溃。使用异步函数可以使程序在执行这些操作的同时继续处理其他任务,提高程序的性能和响应速度。

Node.js 事件循环

Node.js 是一种基于事件驱动的异步 I/O 框架,其核心是事件循环机制。Node.js 中的事件循环机制基于 libuv 库实现,通过处理事件队列中的事件来实现异步处理。

在 Node.js 中,事件循环主要由以下三个部分组成:

  • Timer(定时器阶段):处理 setTimeout()、setInterval() 等定时器事件。
  • I/O callbacks(I/O 回调阶段):处理上一轮循环中未处理的 I/O 回调。
  • Poll(轮询阶段):处理除定时器和 I/O 回调以外的事件,比如网络请求、文件读写等。
  • Check(检查阶段):处理 setImmediate() 回调。
  • Close callbacks(关闭回调阶段):处理 socket.on('close', ...) 等的回调函数。

事件循环机制可以理解为一个循环,每次循环都会执行一个阶段,具体执行哪个阶段取决于事件队列中的待处理事件类型。一个事件循环周期中可能会执行多个阶段,也可能只执行一个阶段。

异步函数在 Node.js 中的运行机制

在 Node.js 中,异步函数会先放入事件队列中等待下一次事件循环去处理。当某个异步事件完成后,事件循环机制会将该事件的回调函数放入事件队列中,等待下一次事件循环去执行。

在事件循环周期中,如果轮询阶段检测到事件队列中有待处理事件,即执行轮询阶段,处理该事件。

以下是一个异步函数在 Node.js 中执行的代码示例:

const fs = require('fs');
const path = require('path');

const filePath = path.join(__dirname, 'test.txt');

// 异步函数,读取文件内容
fs.readFile(filePath, 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

// 其他操作
console.log('Start reading file');

该程序会先输出 Start reading file,然后才输出读取到的文件内容。这是因为 fs.readFile() 函数会先将读取文件的操作放入事件队列中,等待下一次事件循环才会执行该操作并调用回调函数。而其他操作则是同步进行的,不需要等待异步操作的完成。

参考资料