首页
技术小册
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 开发实战
### 异步:异步编程之Promise 在Node.js的开发实践中,异步编程是不可或缺的一部分,它使得应用程序能够处理I/O密集型任务(如文件读写、网络通信等)而不阻塞主线程,从而极大地提高了应用程序的性能和响应能力。在众多异步编程模式中,Promise以其简洁的API和强大的错误处理能力,成为了现代JavaScript和Node.js开发中处理异步操作的主流方式。本章将深入探讨Promise的基本概念、使用方法、链式调用、错误处理以及与其他异步模式的整合,帮助读者掌握这一强大的异步编程工具。 #### 一、Promise的基本概念 Promise是ES6(ECMAScript 2015)引入的一种新的异步编程解决方案,它代表了一个最终可能完成(fulfilled)或失败(rejected)的异步操作及其结果值。Promise对象有三种状态: - **Pending(等待态)**:初始状态,既不是成功,也不是失败状态。 - **Fulfilled(成功态)**:意味着操作成功完成。 - **Rejected(失败态)**:意味着操作失败。 Promise的状态一旦改变,就不会再变。即从pending变为fulfilled或rejected后,状态就固定了。 #### 二、Promise的创建与使用 ##### 2.1 创建Promise Promise对象通过`new Promise()`构造函数创建,该函数接受一个执行器(executor)函数作为参数,执行器函数本身又接受两个函数作为参数:`resolve`和`reject`。`resolve`函数在异步操作成功时被调用,并将操作的结果值作为参数传递;`reject`函数在异步操作失败时被调用,并将错误作为参数传递。 ```javascript let promise = new Promise(function(resolve, reject) { // 异步操作 setTimeout(() => { const result = '操作成功'; if (/* 某些条件 */) { resolve(result); } else { reject(new Error('操作失败')); } }, 1000); }); ``` ##### 2.2 使用Promise Promise对象提供了`.then()`和`.catch()`方法用于处理异步操作的结果或错误。`.then()`方法接收两个可选的回调函数作为参数,第一个函数处理成功的情况,第二个函数(可选)处理失败的情况。`.catch()`方法则是`.then(null, rejection)`的语法糖,仅用于捕获错误。 ```javascript promise.then( result => { console.log(result); // '操作成功' }, error => { console.error(error); // 处理错误 } ).catch(error => { // 捕获前面.then()中未处理的错误 console.error('在catch中捕获的错误:', error); }); ``` #### 三、Promise的链式调用 Promise的一个核心优势在于其支持链式调用,这允许我们按照顺序执行多个异步操作,每个操作都依赖于前一个操作的结果。这是通过返回一个新的Promise对象来实现的。 ```javascript function fetchUser(userId) { return new Promise((resolve, reject) => { // 假设这是从数据库获取用户信息的异步操作 setTimeout(() => { resolve({ id: userId, name: 'Alice' }); }, 1000); }); } function updateUser(user) { return new Promise((resolve, reject) => { // 假设这是更新用户信息的异步操作 setTimeout(() => { resolve(`Updated user: ${user.name}`); }, 500); }); } fetchUser(1).then(user => { return updateUser(user); // 注意这里返回了一个新的Promise }).then(result => { console.log(result); // 'Updated user: Alice' }).catch(error => { console.error('Error:', error); }); ``` #### 四、Promise的错误处理 在Promise链中,一旦某个Promise被`reject`,后续的`.then()`调用中的错误处理函数(即`.then()`的第二个参数)或`.catch()`会立即被调用,并且这个错误会沿着Promise链向后传播,直到被捕获。 ```javascript Promise.reject(new Error('初始错误')) .then(() => { // 这里不会执行 }) .catch(error => { console.error('捕获到的错误:', error.message); // '捕获到的错误: 初始错误' }); ``` 此外,还可以通过`.finally()`方法添加无论Promise最终状态如何都会执行的代码,常用于清理资源等操作。 #### 五、Promise的高级用法 ##### 5.1 Promise.all `Promise.all()`方法接收一个Promise数组作为参数,并返回一个新的Promise实例。只有当所有输入的Promise都成功完成时,返回的Promise才会成功完成,其结果是一个包含所有输入Promise结果的数组。如果任何一个输入的Promise失败,则返回的Promise会立即失败,且失败的原因是最先失败的那个Promise的失败原因。 ```javascript Promise.all([ fetchUser(1), fetchUser(2) ]).then(users => { console.log(users); // [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }] }).catch(error => { console.error(error); }); ``` ##### 5.2 Promise.race 与`Promise.all()`不同,`Promise.race()`方法也是接收一个Promise数组,但它返回一个新的Promise实例,该实例在输入数组中的任何一个Promise被解决(无论是成功还是失败)时,就会被解决,其解决结果与第一个被解决的Promise的结果相同。 ```javascript Promise.race([ fetchUser(1), new Promise((resolve, reject) => setTimeout(reject, 500, '请求超时')) ]).then(user => { // 可能不会执行,取决于哪个Promise先解决 console.log(user); }).catch(error => { console.error(error); // '请求超时' }); ``` #### 六、Promise与其他异步模式的整合 随着JavaScript和Node.js的不断发展,除了Promise之外,还出现了async/await等新的异步编程模式。async/await是建立在Promise之上的,它使得异步代码看起来更像是同步代码,极大地提高了代码的可读性和可维护性。 ```javascript async function fetchAndUpdateUser(userId) { try { const user = await fetchUser(userId); const updated = await updateUser(user); console.log(updated); } catch (error) { console.error('Error:', error); } } fetchAndUpdateUser(1); ``` 在这个例子中,`fetchUser`和`updateUser`函数都返回Promise对象,而`fetchAndUpdateUser`函数则使用了`async`关键字声明为异步函数,并通过`await`关键字等待Promise的解决。这种方式使得异步代码更加直观易懂。 #### 七、总结 Promise作为现代JavaScript和Node.js中处理异步操作的重要工具,其简洁的API和强大的功能使得异步编程变得更加容易理解和维护。通过掌握Promise的基本概念、使用方法、链式调用、错误处理以及与其他异步模式的整合,开发者可以编写出更高效、更可靠的异步代码。希望本章内容能帮助读者深入理解Promise,并在实际开发中灵活运用。
上一篇:
异步:事件循环
下一篇:
异步:异步编程之async/await
该分类下的相关小册推荐:
ES6入门指南
JavaScript入门与进阶
Javascript重点难点实例精讲(一)
JavaScript面试指南
Flutter核心技术与实战
剑指javascript-ES6
Javascript编程指南
深入学习前端重构知识体系
编程入门课:Javascript从入门到实战
Javascript-ES6与异步编程
web前端开发性能优化实战
javascript设计模式原理与实战