Node学习笔记-异步IO详解

[toc]

介绍

学Node都会被告诉,异步是Node的主旋律,大部分Node提供的API都是异步实现的,本章就来一步步介绍异步IO以及它在Node中的实现。

注:本文是学习《深入浅出Node.js》一书的学习笔记,所以参考源码与书上版本一致。(版本:v0.10.13-release)

什么是异步IO

首先了解什么是异步IO,维基百科的解释如下:

异步I/O是计算机操作系统对输入输出的一种处理方式:发起I/O请求的线程不等I/O操作完成,就继续执行随后的代码,I/O结果用其他方式通知发起I/O请求的程序。

按我的理解就是:

你点了个外卖,然后继续忙其他事,等外卖到了给你打个电话,你去取外卖。

异步I/O示意图如下(图片来自《深入浅出Node.js》):

异步IO

这个图更加直观的介绍了异步IO。

当然,这个是我们最理想的异步IO情况,这里的异步IO肯定是有背后的操作去完成调用的IO操作的,我们点个外卖也需要平台管理下商家做和外卖小哥送这一套流程,艺术来源于生活,一般来说异步IO也是这么操作的:

异步IO实现

将单线程的场景转变成多线程,主线程通知IO线程进行IO操作后继续向下执行,IO线程通过阻塞或者非阻塞加轮训的方式取到全部数据后通知到主线程,对于主线程来说,就是一套异步IO操作,即使它是模拟的。

为什么是异步IO

我们都知道Node的核心是异步,那为什么是异步呢?

首先我们要知道,Node是为了写出高性能的web服务器而被设计出来的。既然是web服务器,用户能快速获取到页面是首要任务,请求的资源是一定的,在资源没有很强的依赖关系的情况下,异步请求无疑是个很好的解决方法。

对于浏览器来说,采用异步请求,在下载资源期间,JavaScript和UI的执行都不会处于等待状态,可以继续响应用户的交互行为,给用户一个鲜活的页面。

对于后端web服务器来说,也可以采用这种模式,单线程串行依次执行请求事件,多线程并行处理IO操作。

Node采用了这种模式,利用单线程,远离多线程死锁、状态同步等问题(工作线程有线程池,不需要你管);利用异步I/O,让单线程远离阻塞,以更好地使用CPU。

最后整理下,Node采用异步IO主要有以下考虑:

  1. 快速响应web请求
  2. 充分利用CPU
  3. 避免了编写多线程引发的死锁、状态同步等问题

Node如何实现

事件循环

Node遍布异步事件,各种回调函数穿插,能够完美支持依赖Node自身的执行模型 —- 事件循环

书里的原话介绍的很好,这里就直接引用了:

在进程启动时,Node便会创建一个类似于while(true)的循环,每执行一次循环体的过程我们称为Tick。每个Tick的过程就是查看是否有事件待处理,如果有,就取出事件及其相关的回调函数。如果存在关联的回调函数,就执行它们。然后进入下个循环,如果不再有事件处理,就退出进程。

如下图所示:

事件循环

观察者

请求对象

总结

参考文档

《深入浅出Node.js》——————– 图灵

维基百科-异步I/O

-------------本文结束,感谢您的阅读-------------