Node.js入门教程(十三):Promise
一、什么是 PromisePromise 是 Node.js 中处理异步操作的核心概念之一。Promise 提供了一种更优雅的方式来管理异步代码避免了传统的回调地狱Callback Hell问题。Promise 的三种状态状态说明Pending等待中初始状态既不是成功也不是失败Fulfilled已成功操作成功完成Rejected已失败操作失败Promise 的状态一旦改变从 pending 变为 fulfilled 或 rejected就不会再改变。二、创建 Promise在 Node.js 中可以使用 Promise 构造函数创建新的 Promise 对象const myPromise new Promise((resolve, reject) { // 异步操作 const success true; // 假设这是异步操作的结果 if (success) { resolve(操作成功); // 状态变为 fulfilled } else { reject(操作失败); // 状态变为 rejected } });三、使用 PromisePromise 提供了.then()和.catch()方法来处理成功和失败的情况myPromise .then((result) { console.log(result); // 输出操作成功 }) .catch((error) { console.error(error); // 输出操作失败 });最终操作 .finally()无论 Promise 成功还是失败都会执行.finally()方法适合用于清理资源等操作myPromise .then(result console.log(result)) .catch(error console.error(error)) .finally(() { console.log(操作完成无论成功或失败); });四、Promise 链式调用Promise 的强大之处在于可以链式调用多个异步操作function asyncOperation1() { return new Promise((resolve) { setTimeout(() resolve(第一步完成), 1000); }); } function asyncOperation2(data) { return new Promise((resolve) { setTimeout(() resolve(${data}, 第二步完成), 1000); }); } asyncOperation1() .then((result) asyncOperation2(result)) .then((finalResult) { console.log(finalResult); // 输出第一步完成, 第二步完成 }) .catch((error) { console.error(链式中出错:, error); });五、Promise 的静态方法Promise.all()等待所有Promise 完成或任意一个 Promise 失败const promise1 Promise.resolve(第一个); const promise2 Promise.resolve(第二个); Promise.all([promise1, promise2]) .then((results) { console.log(results); // 输出[第一个, 第二个] }) .catch((error) { console.error(其中一个失败:, error); });Promise.allSettled()等待所有 Promise 完成无论成功或失败const promise1 Promise.resolve(成功); const promise2 Promise.reject(失败); Promise.allSettled([promise1, promise2]) .then((results) { results.forEach(result { if (result.status fulfilled) { console.log(成功:, result.value); } else { console.log(失败:, result.reason); } }); });Promise.race()返回最先完成的 Promiseconst promise1 new Promise((resolve) setTimeout(resolve, 500, 第一个)); const promise2 new Promise((resolve) setTimeout(resolve, 100, 第二个)); Promise.race([promise1, promise2]) .then((result) { console.log(result); // 输出第二个 });Promise.any()返回第一个成功的 Promise忽略失败const promise1 Promise.reject(失败1); const promise2 Promise.resolve(成功2); Promise.any([promise1, promise2]) .then((result) { console.log(result); // 输出成功2 }) .catch((error) { console.log(所有都失败了:, error); });六、错误处理Promise 的错误处理可以通过.catch()或.then()的第二个参数实现// 方式一使用 .catch() someAsyncFunction() .then((result) { /* 处理成功 */ }) .catch((error) { /* 处理所有错误 */ }); // 方式二使用 .then() 的第二个参数 someAsyncFunction() .then( (result) { /* 处理成功 */ }, (error) { /* 处理失败 */ } );错误处理的注意事项// 错误示例如果中间 .then() 中抛出错误后面的 .catch() 会捕获 someAsyncFunction() .then((result) { throw new Error(中间处理出错); }) .catch((error) { console.error(捕获到:, error); }); // 最佳实践链式调用时在所有 .then() 之后只用一个 .catch() fetchData() .then(processData) .then(saveData) .then(displayResult) .catch(error console.error(流程中出错:, error));七、async/await 语法ES2017 引入了 async/await 语法让 Promise 的使用更加直观使异步代码看起来像同步代码async function runOperations() { try { const result1 await asyncOperation1(); const result2 await asyncOperation2(result1); console.log(result2); } catch (error) { console.error(error); } } runOperations();八、常见模式将回调函数转换为 Promiseconst fs require(fs); // 将回调风格的函数转换为 Promise function readFilePromise(filePath) { return new Promise((resolve, reject) { fs.readFile(filePath, utf8, (err, data) { if (err) { reject(err); } else { resolve(data); } }); }); } // 使用 readFilePromise(example.txt) .then(data console.log(data)) .catch(err console.error(err));使用 util.promisifyNode.js 内置了util.promisify工具可以方便地将回调风格的函数转换为返回 Promise 的函数const fs require(fs); const util require(util); const readFilePromise util.promisify(fs.readFile); const writeFilePromise util.promisify(fs.writeFile); // 使用 readFilePromise(example.txt, utf8) .then(data { console.log(data); return writeFilePromise(output.txt, data); }) .then(() console.log(写入完成)) .catch(err console.error(err));九、静态方法对比方法说明触发失败条件Promise.all()等待所有完成任意一个失败Promise.allSettled()等待所有完成永不失败Promise.race()返回最先完成的最先完成的失败则失败Promise.any()返回第一个成功的全部失败十、最佳实践实践说明总是处理错误不要忽略.catch()或 try-catch避免嵌套使用链式调用或 async/await 保持代码扁平命名 Promise给 Promise 变量起有意义的名称返回 Promise在函数中返回 Promise 以便链式调用使用 finally用于清理资源无论成功或失败都执行十一、本章小结知识点说明Promise 状态Pending、Fulfilled、Rejected状态一旦改变不可逆创建 Promisenew Promise((resolve, reject) {})使用 Promise.then()处理成功.catch()处理失败链式调用多个异步操作顺序执行保持代码扁平静态方法Promise.all()、Promise.race()、Promise.any()、Promise.allSettled()async/awaitES2017 语法糖让异步代码像同步代码工具方法util.promisify()将回调函数转为 Promise提示Promise 是现代 Node.js 异步编程的基础。理解 Promise 是掌握 async/await 的前提。建议优先使用 async/await 方式编写异步代码它让异步逻辑更清晰、更易于维护。

相关新闻

《高速公路全覆盖光伏+动态无线充电项目可行性分析》

《高速公路全覆盖光伏+动态无线充电项目可行性分析》

高速公路全覆盖光伏动态无线充电项目可行性分析 该项目的核心构想是将高速公路改造为“发电补能”一体化基础设施:通过路面或上空的光伏板发电,结合路面预埋的动态无线充电线圈,让电动汽车在行驶中实时补能,理论上实现“无限续航”…

2026/9/22 23:47:42 阅读更多 →
AI+小程序开发实战:从技术架构到智能体集成的完整指南

AI+小程序开发实战:从技术架构到智能体集成的完整指南

最近,很多开发者都在问:现在做小程序还有机会吗?是不是红利期已经过了?当“AI小程序”这个组合被微信官方正式推上舞台中央时,答案已经悄然改变。2026微信小程序开发大赛以“AI小程序”为主题,这不仅仅是一…

2026/9/29 15:20:04 阅读更多 →
猎板PCB告诉您:PCB孔铜断裂、CAF短路、分层爆板怎么办?

猎板PCB告诉您:PCB孔铜断裂、CAF短路、分层爆板怎么办?

在新能源汽车、工业控制、电力电源、储能及具身机器人等对可靠性要求极高的领域,一块PCB的失效可能意味着整机系统的瘫痪、安全事故甚至巨额召回成本。据中国电子标准研究院(CEPREI)统计,69%的PCB失效源于生产制程缺陷。而失效导致…

2026/9/27 9:47:01 阅读更多 →

最新新闻

游戏测试面试题底层逻辑:从考官思维到实战应答全解析

游戏测试面试题底层逻辑:从考官思维到实战应答全解析

1. 我为什么劝你先弄懂游戏测试面试的底层逻辑每次看到求职者抱着厚厚的打印题库在面试间门口来回踱步,我都会想起自己刚入行那会儿背了五十道“标准答案”,结果第一轮就被面试官一句“你觉得这题问的是啥”给问懵了。游戏测试面试题看似是考记忆、考套路…

2026/10/1 19:45:19 阅读更多 →
AST语义代码搜索如何做到又快又准?cocoindex-code智能分块与增量索引原理解析

AST语义代码搜索如何做到又快又准?cocoindex-code智能分块与增量索引原理解析

AST语义代码搜索如何做到又快又准?cocoindex-code智能分块与增量索引原理解析 【免费下载链接】cocoindex-code A super light-weight embedded code search engine CLI (AST based) that just works - improves speed and efficiency for coding agent &#x1f31…

2026/10/1 19:45:19 阅读更多 →
Conv2D参数详解:从图像空间计算到工业级CNN设计

Conv2D参数详解:从图像空间计算到工业级CNN设计

1. 为什么Conv2D()的参数不是“填空题”,而是理解CNN架构的钥匙你有没有过这种经历:抄了一段Keras代码,把Conv2D(32, (3, 3), activationrelu)直接粘贴进模型里,训练跑通了,结果在验证集上精度卡在65%不动?…

2026/10/1 19:45:19 阅读更多 →
Redis日志配置全攻略:级别、慢查询、AOF与日志轮转

Redis日志配置全攻略:级别、慢查询、AOF与日志轮转

我在维护一个电商中台的时候,遇到过一件挺打脸的事:线上 Redis 节点 CPU 突然飙到 90%,但监控面板里所有缓存命中率都正常。一群人围着数据扩容讨论了大半天,最后发现罪魁祸首是日志文件写到一半磁盘满了,AOF 重写卡死…

2026/10/1 19:45:19 阅读更多 →
TCP面向字节流为何还要报文头?深度解析粘包问题

TCP面向字节流为何还要报文头?深度解析粘包问题

很多刚开始做网络编程的朋友都问过我同一类问题:TCP 明明是面向字节流的协议,为什么每个数据包还要带一个报文头?既然都叫"流"了,为什么不管一管"粘包"?前几天还有个同学拿一个线上问题来问我——…

2026/10/1 19:45:19 阅读更多 →
解决npm安装报错:淘宝镜像证书过期与npm源切换指南

解决npm安装报错:淘宝镜像证书过期与npm源切换指南

下午三点,新同事抱着电脑来找我,说是Node.js装不上,终端里躺着一行红色报错。我看了一眼,发现是那句眼熟的npm error request to https://registry.npm.taobao.org/cnpm failed, reason: certificate has expired。这个报错我在过…

2026/10/1 19:44:19 阅读更多 →

日新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 19:40:48 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/1 19:41:40 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/30 13:14:49 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →