Node.js中的Promise的作用与知识点讲解

ops/2024/10/22 19:23:21/

Node.js中的Promise的作用与知识点讲解

在Node.js和现代JavaScript编程中,异步编程是一种常见的编程范式,它允许程序在等待某些操作完成时继续执行其他任务。Promise是处理异步操作的一种非常强大的工具,它提供了一种更加清晰和可控的方式来处理异步操作的成功和失败结果。

一. Promise的作用

Promise 是 JavaScript 中用于异步编程的一种解决方案,它代表了一个异步操作的最终完成(或失败)及其结果值。Promise 的作用主要包括以下几点:

  1. 统一异步操作的接口:在 Promise 出现之前,JavaScript 的异步操作通常依赖于回调函数。Promise 提供了一个统一的异步操作接口,使得异步操作可以像同步操作一样通过顺序的代码来处理,这被称为“Promise 链”。

  2. 避免回调地狱:当多个异步操作有依赖关系时,使用回调函数会导致代码嵌套多层,形成所谓的“回调地狱”。Promise 通过链式调用可以避免这种情况,使代码更加清晰。

  3. 状态一旦改变,不可再变Promise 有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。一旦 Promise 的状态从 pending 变为 fulfilled 或 rejected,这个状态就不会再改变,这有助于简化异步逻辑。

  4. 支持成功和失败的处理Promise 提供了 .then() 方法来处理异步操作成功的情况,以及 .catch() 方法来处理失败的情况。这使得错误处理变得更加集中和一致。

  5. 支持finally操作Promise 提供了 .finally() 方法,无论异步操作成功还是失败,都会执行 .finally() 中的代码,这适用于清理资源等需要在异步操作结束后执行的代码。

  6. 可以构造复杂的异步逻辑:通过 Promise.all()Promise.race() 等方法,可以方便地构造多个异步操作的并行、竞态等复杂逻辑。

  7. 更好的错误处理:在回调中,如果一个错误发生,它可能会被忽略,因为回调函数没有 try/catch 语句。而 Promise 可以通过链式调用的 .catch() 方法来捕获整个链中的错误。

  8. 与现代JavaScript特性集成Promise 与现代 JavaScript 的其他特性(如 async/await)集成得很好,使得异步代码可以写得更像同步代码,提高了代码的可读性和可维护性。

总的来说,Promise 提供了一种更强大、更灵活、更易于管理的方式来处理 JavaScript 中的异步操作。

二. Promise的关键知识点

Promise 是 JavaScript 中处理异步操作的核心对象,它代表了一个异步操作的最终完成(或失败)及其结果值。以下是 Promise 的一些关键知识点:

1. Promise 的状态

一个 Promise 对象有三种状态:

  • Pending(进行中):初始状态,既不是成功,也不是失败状态。
  • Fulfilled(已成功):意味着操作成功完成。
  • Rejected(已失败):意味着操作失败。

状态一旦改变,就不会再变,任何时候只能从 Pending 变为 Fulfilled 或 Rejected。

2. 创建 Promise

创建一个 Promise,你需要使用 new Promise 构造函数,并提供一个执行器函数(executor function),它带有两个参数:resolvereject

let myPromise = new Promise((resolve, reject) => {// 异步操作if (/* 成功条件 */) {resolve(value); // 操作成功,调用 resolve} else {reject(reason); // 操作失败,调用 reject}
});

3. 使用 Promise

一旦创建了 Promise,你可以使用 .then().catch() 方法来添加处理成功的回调(成功时调用)和处理失败的回调(失败时调用)。

myPromise.then(value => {// 成功时执行的代码}).catch(error => {// 失败时执行的代码});

4. 链式调用

Promise.then() 方法会返回一个新的 Promise,这允许链式调用。

myPromise.then(result => {// 第一个异步操作的结果return anotherAsyncOperation(result);}).then(newResult => {// 第二个异步操作的结果}).catch(error => {// 任何一个异步操作失败时执行的代码});

5. Promise.all

当需要等待多个异步操作全部完成时,可以使用 Promise.all

Promise.all([promise1, promise2, ...]).then(results => {// 所有 Promise 都成功时执行的代码}).catch(error => {// 任何一个 Promise 失败时执行的代码});

6. Promise.race

Promise.race 接受一个 Promise 数组作为参数,并返回一个新的 Promise,这个新的 Promise 会在数组中任何一个 Promise 完成(成功或失败)时立即完成。

Promise.race([promise1, promise2, ...]).then(result => {// 第一个完成的 Promise 的结果}).catch(error => {// 第一个失败的 Promise 的错误});

7. Promise.resolve 和 Promise.reject

Promise.resolvePromise.reject 用于创建已经成功或失败的 Promise

let resolvedPromise = Promise.resolve(value); // 成功的 Promise
let rejectedPromise = Promise.reject(error); // 失败的 Promise

8. async/await

asyncawait 是基于 Promise 的语法糖,它们提供了一种更简洁的方式来写异步代码。

async function asyncFunction() {try {let result = await myPromise;// 使用 result} catch (error) {// 处理错误}
}

9. 错误处理

Promise 的错误处理非常重要。如果一个 Promise 链中没有 .catch() 方法,那么未捕获的错误可能会导致程序崩溃。

10. 微任务(Microtask)

Promise 的回调函数是在微任务队列中排队的,这意味着它们会在当前执行栈清空后,事件循环的下一阶段执行,而不是在宏任务(如 setTimeout 或 setInterval)之后。

掌握这些 Promise 的关键知识点,可以帮助你更有效地处理 JavaScript 中的异步编程问题。

三. 在项目中的应用

1. 方法1:Promise 原始用法

/*方法1:Promise 原始用法前面如想取到多个sql结果,需要在每个回调函数中逐级嵌套查询通过Promise可以用同步的方式写异步的代码,不用层层嵌套了Promise 基础用法1.创建Promise对象  p1
*/const p1 = new Promise(function(resolve,reject){1.1 放异步任务或代码...1.2返回结果...resolve(data)  //异步任务完成的时候,调用resolve返回结果reject(err)    //异步任务失败的时候,调用resolve返回结果})/*  2.通过then...catch获取Promise对象中的结果then中对应的是成功时候的结果,就是resolve返回的结果catch中对应的是失败时候的结果,就是reject返回的结果Promise 其它API 只Promise.allPromise.all(obj)  obj就promise对象数组,当所有的异步任务完成后,会吧结果依次放入到一个新数组中可以的then的回调函数中取得结果
*/Promise.all([p1,p2]).then(repaire_data=>{console.log(repaire_data)arr.push(repaire_data[0],repaire_data[1]);res.json({ code: 0, msg: "状态条数", data: arr });}).catch(err=>{console.log(err)})

2. 方法2:Promise 原始用法+优化

//方法2:Promise 原始用法+优化const getTotalNum = (status)=>{return new Promise((resolve,reject)=>{return mysql.query(`SELECT count(id) AS total FROM reapply WHERE status = ${status}`, (error, data) => {if (error) {reject(error)console.log(error.sql);} else {resolve(data[0]?.total)// arr.push(totalNum_pass);}});})}Promise.all([getTotalNum(0),getTotalNum(1)]).then(repaire_data=>{console.log(repaire_data)arr.push(repaire_data[0],repaire_data[1]);res.json({ code: 0, msg: "状态条数", data: arr });}).catch(err=>{console.log(err)})

3. 方法3:Promise 原始用法+优化+async await

await 是更好的异步解决方案,更简洁。不需要用then…catch,await等待的是Promise对象里面then的结果。

用到await的函数需要async function(){}来标记。

//方法3:Promise 原始用法+优化+async awaitconst getTotalNum = (status)=>{return new Promise((resolve,reject)=>{return mysql.query(`SELECT count(id) AS total FROM reapply WHERE status = ${status}`, (error, data) => {if (error) {reject(error)console.log(error.sql);} else {resolve(data[0]?.total)// arr.push(totalNum_pass);}});})}// 错误处理,使用try...catchtry{// 成功let num01 = await getTotalNum(0)let num02 = await getTotalNum(1)let num03 = await getTotalNum(2)let num04 = await getTotalNum(3)let num05 = await getTotalNum(-1)let num06 = await getTotalNum(-2)res.json({ code: 0, msg: "状态条数", data: [num01,num02,num03,num04,num05,num06] });}catch{// 失败res.json({ code: -1, msg: "状态条数", data: [] });}

四. 结论

Promise是Node.js和现代JavaScript中处理异步操作的强大工具。它通过提供一种结构化的方式来处理异步操作的成功和失败结果,使得代码更加清晰、易于维护,并且可以有效地并行处理多个异步操作。掌握Promise的使用,对于任何JavaScript开发者来说都是非常重要的。


http://www.ppmy.cn/ops/124143.html

相关文章

【Linux】Linux 环境变量中 LOGNAME 和 USER 有什么本质区别

一、概念 在 Linux 中,LOGNAME和 USER都是环境变量,用于表示当前用户的用户名。 二、区别点 LOGNAME: 在某些情况下,它可能会保持不变,即使用户通过 su 命令切换到其他用户。 USER: 在使用 su 命令切换用户时,…

使用C++的OpenSSL 库实现 AES 加密和解密文件

如果C不知道做什么项目,可以编写一个文件加密和解密工具,支持诸如 AES 和 RSA 等常见的加密算法。这样的项目可以帮助学习和理解现代加密技术,并为日常文件保护提供便利。以下是一个基本的设计思路和实现步骤: 1. 设计思路 a. 功…

CSRF | POST 型 CSRF 漏洞攻击

关注这个漏洞的其他相关笔记:CSRF 漏洞 - 学习手册-CSDN博客 0x01:POST 型 CSRF 漏洞攻击 —— 理论篇 POST 型 CSRF 漏洞是指攻击者通过构造恶意的 HTTP POST 请求,利用用户的登录状态,在用户不知情的情况下,诱使浏览…

声波定位给我们日常生活带来哪些便利

在科技日新月异的今天,声波定位技术作为一项前沿科技,正悄然改变着我们的生活方式,为日常生活带来了前所未有的便利与惊喜。这项技术,通过发射声波并接收其反射回来的信号,精确测量物体位置或距离,不仅在科…

Kubernetes(K8s)的简介

一、Kubernetes的简介 1 应用部署方式演变 在部署应用程序的方式上,主要经历了三个阶段: 传统部署:互联网早期,会直接将应用程序部署在物理机上 优点:简单,不需要其它技术的参与 缺点:不能为应…

GR-ConvNet论文 学习笔记

GR-ConvNet 文章目录 GR-ConvNet前言一、引言二、相关研究三、问题阐述四、方法A.推理模块B.控制模块C.模型结构D.训练方法E.损失函数 五、评估A.数据集B.抓取评判标准 六、实验A.设置B.家庭测试物体C.对抗性测试物体D.混合物体 七、结果A.康奈尔数据集B.Jacquard数据集C.抓取新…

git clone 私有仓库时出现错误 Authentication failed for :xxxxxx

错误信息 remote: Support for password authentication was removed on August 13, 2021. remote: Please see https://docs.github.com/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended…

低代码赋能汽车制造产业链场景系列

当前汽车行业数字化智能化转型浪潮下,整车及其上下游产业链的协同创新正变得至关重要。头部车企与上下游供应链企业正逐步解决在生产管理、业务互通、系统集成等方面的痛点与挑战。电动化、智能化、网联化作为汽车产业的三大趋势,正共同推动未来汽车产业…