Node异步式I/O和异步式编程(三)

mulan 2017-12-07 14:56:43 ⋅ 906 阅读

 Node.js 最大的特点就是异步式 I/O(或者非阻塞I/O)与事件紧密结合的编程模式。


第一部分: I/O

1.阻塞I/O与非阻塞I/O概念

1.1阻塞I/O(同步I/O)

线程在执行中如果遇到磁盘读写或网络通信(**统称为I/O 操作**), 通常要耗费较长的时间,这时操作系统会剥夺这个线程的 CPU 控制权,使其暂停执行,同时将资源让给其他的工作线程,这种线程调度方式称为**阻塞**,当**I/O 操作**完成时,操作系统将这个线程的阻塞解除,恢复其对CPU的控制 ,令其继续运行。这种 I/O 模式就是通常的**同步式 I/O(Synchronous I/O)或阻塞式 I/O (Blocking I/O)。

1.2非阻塞I/O(异步I/O)

非阻塞I/O是针对所有的I/O**不采用阻塞的策略**, 当线程遇到I/O 操作时, **不会阻塞等待完成**, 而是将I/O 操作发送给操作系统, **继续执行下一个语句**, 等操作系统完成I/O 操作以后, 会以**事件的形式**发送通知执行I/O 操作的线程, 线程会在特定的时候处理这个事件; 也就是线程中会不停的监听时间循环, 看是否有未处理的事件, 并以此处理.


举个通俗的例子:

[例子来自知乎网友](https://www.zhihu.com/question/19732473/answer/20851256)


```

你打电话问书店老板有没有《分布式系统》这本书,如果是`同步通信机制`,书店老板会说,你稍等,”我查一下",

然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。


而`异步通信机制`,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。

然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。

```

2.阻塞I/O与非阻塞I/O特点

      



第二部分 异步式编程(函数式编程)

有异步I/O,就必然有异步编程。    

首先以同步式编程的语法读取一个文件:


*创建readfilesync.js, 并执行*


```

var fs = require('fs');

var data = fs.readFileSync('/Users/51testing/Desktop/file.txt', 'utf-8'); 

console.log(data);

console.log('end.');     

```

打印的结果如下:


```

//执行

$ node /Users/51testing/Desktop/readfilesync.js 

你好呀

end.

```


以上代码很容易理解, 自上而下的执行, 那么异步编程的做法呢?


*创建readfileasync.js, 并执行*


```

var fs = require('fs');

fs.readFile('/Users/51testing/Desktop/file.txt', 'utf-8', function(err, data) {

if (err){ 

    console.error(err);

} else { 

    console.log(data);

});

    console.log('end.');

```


打印的结果如下:


```

//执行

$ node /Users/51testing/Desktop/readfileasync.js 

end.

你好呀

```


fs.readFile 调用时所做的工作只是`将异步式 I/O 请求发给了操作系统`, 然后`立即返回`并执行后面的语句,执行完以后进入事件循环监听事件。 

 fs 接到I/O 请求完成的事件时,`事件循环会主动调`回调函数以完成后续工作。`因此我们会先看到 end.然后看到 file.txt 文件的内容。`



第三部分 Node.js循环机制



> Node.js 在什么时候会进入事件循环呢? 


**生命周期为:**`Node.js 程序由事件循环环开始,到事件循环结束`.


所有的逻辑都是事件的回调函数,所以 Node.js 始终在事件循环中,程序入口就是 事件循环第一个事件的回调函数。事件的回调函数在执行的过程中,可能会发出 I/O 请求或直接发射  (emit)事件,执行完成后再返回事件 循环,事件循环会会检查循环中有没有  处理的事件,直到到程序结束。




全部评论: 0

    我有话说:

    Tokio 1.0 发布,Rust 异步编程框架

    Tokio 1.0 稳定版本已发布,Tokio 是 Rust 的异步 runtime,可用于编写快速、可靠的网络应用。Tokio 还提供用于 TCP、UDP、计时器、多线程、工作窃取算法(work

    Git中心工作流程

    Git中心工作流程

    Node实战篇:Express路由()

    Express 是一个基于 Node.js 平台的极简、灵活的 web 应用开发框架,它提供一系列强大的特性,帮助你创建各种 Web 移动设备应用。

    Node模块之fs模块(六)

    屏幕快照 2017-08-08 上午10.53.21.png 第一部分 概述 Node.js 提供一组类似UNIX(POSIX)标准的文件操作API,Node.js中操作文件的模块是fs(File

    Spring 5 的 WebFlux 响应开发示例

    Spring 5 已经大力支持了响应开发模式,引入的响应框架叫做 Spring WebFlux。

    Mongoose 5.12.5 发布,MongoDB 异步对象模型工具

    Mongoose 是设计用于异步环境的 MongoDB 对象模型工具。Mongoose 支持 promises callbacks。Mongoose 5.12.5 正式发布,本次更新内容如下

    Fizz Gateway 1.1.1 发布,基于 Java异步框架WebFlux开发的微服务网关

    Fizz Gateway 是一个基于 Java异步框架WebFlux开发的微服务网关,能够实现热服务编排、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理等目的,拥有强大的自定义

    Netty 4.1.59.Final 发布,异步事件驱动的网络应用框架

    Netty 4.1.59.Final 已经发布。Netty 是一个异步事件驱动的网络应用框架,主要用于可维护的高性能协议服务器客户端的快速开发。 该版本除了修复各种错误之外,还包含一个安全修复程序

    Netty 4.1.60.Final 发布,异步事件驱动的网络应用框架

    Netty 4.1.60.Final 已经发布。Netty 是一个异步事件驱动的网络应用框架,主要用于可维护的高性能协议服务器客户端的快速开发。本次更新除了修复各种错误之外,还包含了一个安全修复

    Netty 4.1.61.Final 发布,异步事件驱动的网络应用框架

    Netty 4.1.61.Final 已经发布。Netty 是一个异步事件驱动的网络应用框架,主要用于可维护的高性能协议服务器客户端的快速开发。本次更新除了修复各种错误之外,还包含了一个安全修复

    Netty 4.1.65.Final 发布,异步事件驱动的网络应用框架

    Netty 4.1.65.Final 已经发布。Netty 是一个异步事件驱动的网络应用框架,主要用于可维护的高性能协议服务器客户端的快速开发。本次更新除了修复各种错误之外,还包含了一个安全修复

    架构实战篇(五):Spring Boot 表单验证异常处理

    为了让API 能够更好的提供服务,表单数据验证异常的处理是必不可少的,让我们来看看怎么处理......

    微信小程序电商实战-商品列表流布局

    今天给大家分享一下微信小程序中商品列表的流布局方式,根据文章内容操作就可以看到效果哦~~~

    Node模块之Events模块(五)

    Node模块之Events模块(五)

    JavaScript作业队列微任务

    JavaScript作业队列微任务 当Promises在ES6中首次引入时,它们使编写异步代码的工作变得更加容易。回调地狱被更简单的构造所取代,该构造使开发人员可以更轻松地处理异步任务。理解诺言的

    Nodejs视频服务器 切片ffmpeg

    Node 视频服务器 切片ffmpeg

    Node实战篇:Express--jade模板引擎(七)

    Jade(Pug) — Node Template Engine,一个高性能的模板引擎,专为 Node 而做......

    Node包管理NPM(二)

    code; manage dependencies i...

    Jetpack Compose for Desktop 添加 Swing 互操作层 Apple Silicon 支持

    Jetpack Compose for Desktop 是软件开发厂商 JetBrains 推出的一个 Kotlin 桌面 UI 框架,采用声明响应的方法构建 UI。简化并