深入浅出Node.js读书笔记:Node.js的异步I/O(3.3)

本节介绍Node是如何实现异步I/O的,除了讨论I/O模型外,还将讨论Node的执行模型。完成整个异步I/O环节的有事件循环,观察者和请求对象等。

3.3.1 事件循环

先来看下Node自身的执行模型—事件循环。在Node启动时,它会创建一个类似于while的循环,执行一次的过程称为Tick,每个Tick执行过程就是查看是否有事件要处理,如果有,就取出然后执行,执行后,如果有关联函数,就执行它们。

3.3.2 观察者

在每个Tick过程中,如何判断有新的事件需要处理呢?这里引入观察者概念。

每个事件循环都有一个或多个观察者,而判断是否有事件处理的过程就是向观察者询问是否有事件要处理。

浏览器就是采用类似机制。事件可能来自用户点击或者加载某些文件时,而产生的事件都有对应的观察者。在Node中,网络请求,文件IO对应的观察者有网络I/O观察者,文件I/O观察者。观察者将事件进行了分类。

事件循环是一个典型的生产者/消费者模型。异步I/O,网络请求等则是事件的生产者,将事件传递给观察者,事件循环则从观察者那取出事件进行处理。

3.3.3 请求对象

这节通过windows下异步I/O的简单例子,来探寻从Javascript代码到系统内核之间都发生了什么。

对于Node中的异步I/O调用而言,回调函数却不由开发者调用。那么从发出调用后,到回调函数被执行,中间发生了什么?

从Javascript发起调用到内核执行完I/O操作的过度过程中,存在一种中间产物,它叫做请求对象。

通过fs举例,比如fs.open方法,整个调用栈如下:从Javascript调用Node的核心模块,核心模块调用c++内建模块,内建模块通过libuv进行系统调用,这里libuv对不同平台的功能进行了封装。具体到某个平台,会把该消息分发到各个平台自己实现的线程池中执行,Javascript调用至此完成。

Javascript线程可以继续执行后续任务,不会影响IO操作,不管它是阻塞,都不会影响Javascript线程的后续任务执行。

3.3.4 执行回调

组装完请求对象,送入线程池等待执行,至此已经完成第一阶段。

当线程池中的IO操作执行完后,会将返回的结果,存储到事件循环中并告知观察者。观察者取出回调函数和结果调用执行。

事件循环,观察者,请求对象,I/O线程池这四者共同构成了Node异步I/O模型的基本要素。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值