首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
Node.js是什么?
Node.js可以用来做什么?
什么是技术预研?
Node.js开发环境安装
第一个Node.js程序:石头剪刀布游戏
模块:CommonJS规范
模块:使用模块规范改造石头剪刀布游戏
模块:npm
模块:Node.js内置模块
异步:非阻塞I/O
异步:异步编程之callback
异步:事件循环
异步:异步编程之Promise
异步:异步编程之async/await
HTTP:什么是HTTP服务器?
HTTP:简单实现一个HTTP服务器
HTTP:实现网页版石头剪刀布
HTTP:用express优化石头剪刀布游戏
HTTP:用koa优化石头剪刀布游戏
RPC 调用:什么是RPC调用?
RPC调用:Node.js Buffer编解码二进制数据包
RPC 调用:Node.js net建立多路复用的RPC通道
项目启动:整体需求分析
项目启动:码小课App下载页开发
课程详情页:码小课详情页需求解构
课程详情页:将ES6模版字符串改造成模板引擎
课程详情页:码小课详情页需求实现
课程播放页:码小课播放页需求解构
课程播放页:GraphQL API服务
课程播放页:码小课播放页需求实现
课程列表页:码小课列表页需求解构
课程列表页:用 Vue/React 进行服务端渲染
课程列表页:码小课列表页需求实现
性能工具:HTTP服务的性能测试
性能工具:Node.js性能分析工具
代码优化:JavaScript代码性能优化
代码优化:内存管理优化
代码优化:Node.js C++插件
多进程优化:Node.js子进程与线程
多进程优化:Node.js cluster模块实战与源码解读
多进程优化:进程守护与管理
架构优化:动静分离
架构优化:反向代理与缓存服务
概念:框架设计和工程化
概念:设计模式
概念:Serverless
服务端框架搭建:koaless
服务端框架搭建:屏蔽请求细节
服务端框架搭建:完成服务端框架
云函数式工程实现:服务端代码
云函数式工程实现:工具端代码
当前位置:
首页>>
技术小册>>
Node.js 开发实战
小册名称:Node.js 开发实战
### 异步:非阻塞I/O 在Node.js的开发世界中,异步与非阻塞I/O(输入/输出)是核心概念,它们共同构建了Node.js高效、高性能的基石。这一章将深入探讨异步编程的原理、Node.js如何实现非阻塞I/O、以及如何在实际开发中有效利用这些特性来提升应用的性能和响应能力。 #### 一、异步编程基础 **1.1 同步与异步的区别** 首先,我们需要明确同步(Synchronous)与异步(Asynchronous)的基本概念。在同步编程模型中,程序按照代码的顺序逐行执行,直到当前操作完成,才会继续执行下一个操作。这种模式下,如果某个操作耗时较长(如网络请求、文件读写等),整个程序将处于等待状态,无法继续执行其他任务,这会导致资源的浪费和用户体验的下降。 相比之下,异步编程允许程序在等待某个操作完成时,继续执行其他任务。当异步操作完成时,会通过回调函数、Promises、async/await等方式通知程序处理结果。这种方式极大提高了程序的并发处理能力和响应速度。 **1.2 Node.js与异步编程** Node.js是一个基于Chrome V8引擎的JavaScript运行环境,它天生支持异步编程。Node.js的设计哲学是“事件驱动,非阻塞I/O”,这意味着Node.js应用通过监听和处理事件来运行,同时利用非阻塞I/O操作来避免在I/O密集型任务中阻塞主线程。 #### 二、非阻塞I/O详解 **2.1 什么是I/O操作** I/O操作,即输入/输出操作,是计算机程序与外部世界(如文件系统、数据库、网络等)交互的方式。常见的I/O操作包括文件读写、网络通信、数据库查询等。 **2.2 阻塞I/O与非阻塞I/O** - **阻塞I/O**:在执行I/O操作时,程序会暂停执行,直到I/O操作完成。这种模式下,如果I/O操作耗时较长,将导致程序无法响应其他请求,降低整体性能。 - **非阻塞I/O**:在发起I/O操作后,程序不会等待I/O操作完成,而是立即返回继续执行后续代码。当I/O操作完成时,会通过某种机制(如回调函数、事件等)通知程序处理结果。这种方式提高了程序的并发性和响应速度。 **2.3 Node.js中的非阻塞I/O实现** Node.js使用libuv库作为其底层跨平台的异步I/O解决方案。libuv封装了不同操作系统提供的异步I/O机制(如Linux的epoll、Windows的IOCP等),为Node.js提供了一个统一的、高性能的异步I/O接口。 当Node.js执行一个I/O操作时(如读取文件),它会将这个操作交给libuv处理。libuv将这个操作放入系统的事件循环中,并立即返回,允许Node.js继续执行其他任务。当I/O操作完成时,libuv会通过事件的方式通知Node.js,Node.js再调用相应的回调函数来处理结果。 #### 三、异步编程模式 **3.1 回调函数** 回调函数是Node.js中最基础的异步编程模式。在发起异步操作时,我们将一个函数作为参数传递给异步函数,这个函数将在异步操作完成时被执行。然而,回调函数的使用容易导致“回调地狱”(Callback Hell),即多层嵌套的回调函数使得代码难以阅读和维护。 **3.2 Promises** 为了解决回调地狱的问题,ES6引入了Promises。Promises提供了一种更优雅的方式来处理异步操作的结果。Promise对象代表了一个可能现在还不可用,但将来某一时刻会变为可用的值或结果。通过Promise的链式调用(.then()、.catch()),我们可以将异步操作组织成更加清晰、易于理解的代码结构。 **3.3 async/await** 在ES2017中,async/await的引入进一步简化了异步编程的复杂性。async关键字用于声明一个异步函数,该函数返回一个Promise对象。await关键字只能在async函数内部使用,它用于等待一个Promise对象解析完成,并返回解析的结果。await使得异步代码看起来和同步代码几乎一样,极大地提高了代码的可读性和可维护性。 #### 四、异步编程实践 **4.1 异步文件操作** Node.js提供了`fs`模块来支持文件系统的异步操作。通过`fs.readFile`、`fs.writeFile`等API,我们可以以非阻塞的方式读取和写入文件。 ```javascript const fs = require('fs'); fs.readFile('example.txt', 'utf8', (err, data) => { if (err) throw err; console.log(data); }); // 使用Promises fs.promises.readFile('example.txt', 'utf8') .then(data => console.log(data)) .catch(err => console.error(err)); // 使用async/await async function readFileAsync() { try { const data = await fs.promises.readFile('example.txt', 'utf8'); console.log(data); } catch (err) { console.error(err); } } readFileAsync(); ``` **4.2 异步网络请求** Node.js的`http`和`https`模块支持异步的网络请求处理。此外,还有第三方库如`axios`、`node-fetch`等提供了更加丰富的HTTP客户端功能。 ```javascript const axios = require('axios'); async function fetchData() { try { const response = await axios.get('https://api.example.com/data'); console.log(response.data); } catch (error) { console.error('Error fetching data:', error); } } fetchData(); ``` **4.3 异步数据库操作** 对于数据库操作,Node.js社区提供了多种异步数据库客户端,如MongoDB的`mongoose`、MySQL的`mysql2/promise`等。这些客户端允许我们以非阻塞的方式执行数据库查询和更新操作。 ```javascript const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/mydb', { useNewUrlParser: true, useUnifiedTopology: true }); const Schema = mongoose.Schema; const UserSchema = new Schema({ name: String, email: String }); const User = mongoose.model('User', UserSchema); async function createUser() { try { const newUser = new User({ name: 'John Doe', email: 'john@example.com' }); await newUser.save(); console.log('User created successfully!'); } catch (error) { console.error('Error creating user:', error); } } createUser(); ``` #### 五、总结 异步与非阻塞I/O是Node.js的核心特性之一,它们共同构成了Node.js高效、高性能的基础。通过深入理解异步编程的原理和Node.js的非阻塞I/O实现机制,我们可以更加灵活地利用这些特性来编写出高性能、高响应性的Node.js应用。同时,随着JavaScript异步编程模式的不断演进(从回调函数到Promises,再到async/await),我们也有了更多的选择来优化我们的代码结构和提升代码的可读性。
上一篇:
模块:Node.js内置模块
下一篇:
异步:异步编程之callback
该分类下的相关小册推荐:
经典设计模式Javascript版
Javascript-ES6与异步编程
ES6入门指南
深入学习前端重构知识体系
Javascript编程指南
web前端开发性能优化实战
剑指javascript-ES6
JavaScript入门与进阶
Flutter核心技术与实战
npm script实战构建前端工作流
编程入门课:Javascript从入门到实战
剑指javascript