4-异步:非阻塞I_O
简介
什么是Node.js的非阻塞I/O
- I/O 即 Input/Output. 也就是一个系统的输入和输出
- 阻塞I/O和非阻塞I/O的却别就在于系统接收输入再到输出期间,能不能接收其他输入
对于这两句话的理解,可以把系统比作服务员,阻塞I/O类型的服务员是同一时间只能只能完整处理一个人的业务,处理完一个人后,才会到下一个人;非阻塞I/O类型的服务员则是可以先让客户预定,且预定完后,可以有精力去办理另一个人的预定,如果某个客户预定业务完成,就再去通知客户即可。
这样看来非阻塞I/O的服务员的运作模式更符合现在数量多的客户群体,阻塞I/O则相反。
更简单的理解,比如你遇到一个难解的问题,在线上进行了提问,提问后等待回答的过程中,如果你因为这个问题没得到解答前无法开展其它工作,那么这就是阻塞I/O,如果你可以先去做其它的工作,那么就是非阻塞I/O。
注意:在服务员和客户的例子中,存在一个问题,如果服务员数量少,客户多,服务员处理不过来,也会造成业务的阻塞,因此,看待阻塞和非阻塞问题,应该从宏观上来看,关注点不是在处理业务这个步骤,而应该是关注在接受业务-等待业务处理-业务处理完成这个流程,在这个流程中,等待业务处理时,服务员是否可以去处理其它业务就是判断阻塞和非阻塞的重要依据。
线程方式理解NodeJs
回到在NodeJs内置模块中提到的这幅 NodeJs 系统图。
在上面理解了非阻塞和阻塞I/O的概念后,我们可以把这幅图按照线程的模式进行划分区域。
如下图,左边部分是 node.js 线程,右边部分是 其它 c++ 线程,当我们左边的应用代码工作时,就是在 node.js 线程中运行,如果使用到了node.js 中的 I/O 操作(node.js 中所有 I/O 操作都是非阻塞的),就需要将该操作放到右边其它 c++ 的线程进行执行,执行后将结果又返回左边 node.js 线程中进行使用即可。
因此,按照线程的模式就可以划分为 node.js 线程 和 c++ 线程。
而且,在 node.js 底层非阻塞的实现也是通过线程来实现的。
注意:异步 和 非阻塞I/O 不是同一个东西,异步是指一种编程的方式,非阻塞 I/O 是一个底层机制的名字。