AJAX-Promise 详解

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)

目录

前言

一、Promise基本概念

1.1 定义

1.2 状态

1.3 构造函数

二、Promise基本用法

2.1 then()

2.2 catch()

2.3 链式调用

三、Promise高级特性

3.1 Promise.all()

3.2 Promise.allSettled()

3.3 Promise.race()

3.4Promise.any()

四. Promise的调试与优化

4.1 使用async/await

4.2 错误处理

4.3 并行执行

4.4 性能优化

五. 结论


前言

在JavaScript的异步编程世界中,Promise无疑是一个里程碑式的存在。它提供了一种更加优雅和强大的方式来处理异步操作,解决了传统回调函数的“回调地狱”问题,使得代码更加清晰、易于维护。本文将深入探索Promise的各个方面,包括其基本概念、基本用法、链式调用、错误处理、静态方法、与async/await的结合使用,以及在实际项目中的应用。

一、Promise基本概念

1.1 定义

Promise是JavaScript中的一个对象,它代表了一个尚未完成但预期将来会完成的异步操作的结果。它允许你为异步操作的成功(fulfilled)和失败(rejected)注册回调函数。

1.2 状态

Promise有三种状态:

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

一旦Promise被fulfilled或rejected,它的状态就不能再改变。

1.3 构造函数

Promise的构造函数接收一个执行器(executor)函数作为参数,该执行器函数本身又接收两个函数作为参数:resolve和reject。

let promise = new Promise(function(resolve, reject) {  // 异步操作  if (/* 异步操作成功 */) {  resolve(value); // 将Promise的状态从"pending"变为"fulfilled",并将value作为操作成功的结果  } else {  reject(error); // 将Promise的状态从"pending"变为"rejected",并将error作为操作失败的原因  }  
});

二、Promise基本用法

2.1 then()

then()方法用于指定Promise成功时(即fulfilled时)的回调函数,并返回一个新的Promise实例。

promise.then(function(value) {  // 当Promise成功时执行  console.log(value);  
}, function(error) {  // 可选:当Promise失败时执行(但通常不推荐这种方式,因为会破坏链式调用)  console.error(error);  
});

2.2 catch()

catch()方法是.then(null, rejection)的语法糖,用于指定Promise失败时(即rejected时)的回调函数。

promise.then(function(value) {  // 成功时执行  
}).catch(function(error) {  // 失败时执行  console.error(error);  
});

2.3 链式调用

Promise支持链式调用,因为then()catch()方法都会返回一个新的Promise实例。

fetch('https://api.example.com/data')  .then(response => response.json())  .then(data => {  console.log(data);  })  .catch(error => {  console.error('Fetch error:', error);  });

三、Promise高级特性

3.1 Promise.all()

Promise.all()方法接收一个Promise对象的数组作为参数,并返回一个新的Promise实例。只有当数组中的所有Promise都被fulfilled时,返回的Promise才会被fulfilled,其结果是一个包含所有fulfilled值的数组。

let promise1 = Promise.resolve(3);  
let promise2 = 42;  
let promise3 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'foo'));  Promise.all([promise1, promise2, promise3]).then(values => {  console.log(values); // [3, 42, "foo"]  
});

3.2 Promise.allSettled()

Promise.allSettled()是ES2020中引入的一个新方法,它类似于Promise.all(),但不同之处在于它等待所有给定的Promise都完成(无论是fulfilled还是rejected),并返回一个数组,数组中的每个元素都是一个对象,描述了对应Promise的结果。

const promise1 = Promise.resolve(3);  
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 50, 'rejection'));  
const promise3 = new Promise((resolve) => setTimeout(resolve, 100, 'foo'));  Promise.allSettled([promise1, promise2, promise3]).then((results) => {  results.forEach((result) => {  if (result.status === 'fulfilled') {  console.log('fulfilled:', result.value);  } else if (result.status === 'rejected') {  console.log('rejected:', result.reason);  }  });  // 输出:  // fulfilled: 3  // rejected: rejection  // fulfilled: foo  
});

3.3 Promise.race()

Promise.race()方法返回一个新的Promise,该Promise以输入数组中第一个解决(无论是fulfilled还是rejected)的Promise的结果作为自己的结果。这在处理具有超时限制或需要快速响应的场景时非常有用。

const fastPromise = new Promise((resolve) => setTimeout(resolve, 100, 'Fast one won'));  
const slowPromise = new Promise((resolve) => setTimeout(resolve, 500, 'But I am here too'));  Promise.race([fastPromise, slowPromise]).then((value) => {  console.log(value); // 输出: Fast one won  
}).catch((error) => {  console.error('An error occurred', error);  
});

3.4Promise.any()

Promise.any()是ES2020中引入的另一个静态方法,它返回一个新的Promise,该Promise以输入数组中第一个成功(fulfilled)的Promise的结果作为自己的结果。如果所有输入的Promise都失败了,则返回的Promise将拒绝(reject),并抛出一个AggregateError,表示所有Promise都失败了。

const promise1 = new Promise((resolve, reject) => setTimeout(reject, 500, 'First failed'));  
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'Second succeeded'));  
const promise3 = new Promise((resolve, reject) => setTimeout(reject, 150, 'Third failed'));  Promise.any([promise1, promise2, promise3]).then((value) => {  console.log(value); // 输出: Second succeeded  
}).catch((errors) => {  console.error('All promises failed', errors);  // 在这个例子中,这个catch块不会被执行  
});

四. Promise的调试与优化

在使用Promise进行异步编程时,合理的调试和优化是提高代码质量和性能的关键。以下是一些建议:

  • 使用浏览器的开发者工具:利用浏览器的网络监控、断点调试等功能来跟踪Promise的状态和值。
  • 避免创建不必要的Promise链:保持Promise链的简洁性,避免过长的链式调用,以减少回调地狱(Callback Hell)的发生。
  • 利用async/await简化异步代码async/await是JavaScript中处理异步操作的现代、更简洁的语法糖,它们基于Promise构建,可以让异步代码看起来和同步代码一样。以下是如何利用async/await来进一步简化和优化Promise的使用。

4.1 使用async/await

async关键字用于声明一个异步函数,该函数会隐式地返回一个Promise。在async函数内部,你可以使用await关键字来等待一个Promise解决,而无需显式地编写.then().catch()链。

async function fetchData() {  try {  const response = await fetch('https://api.example.com/data');  const data = await response.json();  console.log(data);  } catch (error) {  console.error('Failed to fetch data:', error);  }  
}  fetchData();

在这个例子中,fetchData函数是异步的,它使用await来等待fetch调用和JSON解析的结果。如果任何一个await表达式失败,控制流将跳转到catch块。

4.2 错误处理

在使用async/await时,错误处理变得非常直观。你可以使用标准的try...catch语句来捕获和处理异步操作中发生的错误。

async function fetchAndProcessData() {  try {  const data = await fetchData(); // 假设fetchData是一个返回Promise的异步函数  // 处理数据  } catch (error) {  console.error('Error processing data:', error);  }  
}

4.3 并行执行

虽然async/await使代码看起来像是同步的,但你不应该用它来并行执行多个异步操作。对于这种情况,你应该使用Promise.all()或其他并行执行的方法,然后在async函数中使用await等待所有操作完成。

async function fetchMultipleData() {  const promises = [  fetch('https://api.example.com/data1'),  fetch('https://api.example.com/data2')  ];  const [response1, response2] = await Promise.all(promises);  const [data1, data2] = await Promise.all([response1.json(), response2.json()]);  console.log(data1, data2);  
}  fetchMultipleData();

4.4 性能优化

  • 避免不必要的等待:不要在没有必要时使用await,特别是在循环或频繁调用的函数中。
  • 使用缓存:对于重复请求相同资源的情况,考虑使用缓存来避免不必要的网络请求。
  • 限制并发请求:如果你的应用需要发送大量并发请求,考虑限制同时进行的请求数量,以避免资源耗尽。

五. 结论

Promise是JavaScript中处理异步操作的重要工具,而async/await则为它们的使用提供了更简洁、更直观的语法。通过合理使用Promise的高级特性和async/await,你可以编写出既清晰又高效的异步代码。然而,重要的是要记住,异步编程的本质并未改变,只是工具和语法变得更加方便和强大。因此,理解和掌握异步编程的基本概念仍然是至关重要的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/50808.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

keras的路透社数据训练对测试数据的概率总和计算问题

在使用keras内置数据路透社新闻分类的时候,使用训练的模型预测测试数据。然后发现对预测数据分类的概率总和不是1. pridiction model.predict(x_test)for i in range(0,46):print(np.sum(pridiction[i]))然而python深度学习这本书里面的是1.0 问题目前没有解决。…

掌握 Symfony 路由系统:配置与管理

掌握 Symfony 路由系统:配置与管理 Symfony 是一个非常流行的 PHP 框架,而路由系统是 Symfony 框架的核心组件之一。通过理解和掌握 Symfony 的路由系统,开发者可以更高效地配置和管理应用程序的 URL 结构,从而更好地控制应用程序…

醒醒,别睡了...讲《数据分析pandas库》了—/—<3>

直接上知识点 一、 1、新建数据框时建立索引 所有的数据框默认都已经使用从 0 开始的自然数索引,因此这里的"建立”索引指的是自定 df pd.DataFrame( {varl : 1.0, var2 :[1,2,3,4], var3 :[test,python,test,hello] , var4 : cons} , index [0,1,2,3]) …

量化私募公司的多因子构建方案(附python代码)

原创文章第600篇,专注“AI量化投资、世界运行的规律、个人成长与财富自由"。 昨天代码已经发布了,大家可以前往下载和更新: 代码发布:quantlabv5.3,可转债所有数据及双低、动量因子策略,单因子分析框…

文件夹怎么设置密码?文件夹加密方法盘点

文件夹是电脑管理数据的重要工具,当我们将重要数据存储在文件夹中时,需要严格保护文件夹的数据安全,避免数据泄露。下面我们就来了解一下文件夹设置密码的方法。 文件夹加密 文件夹加密是指通过加密算法来加密保护文件夹,避免其他…

人工蜂鸟算法(Artificial Hummingbird Algorithm,AHA)及其Python和MATLAB实现

### 背景 人工蜂鸟算法(Artificial Hummingbird Algorithm,AHA)是一种新兴的群体智能优化算法,受到自然界中蜂鸟觅食行为的启发。蜂鸟以其独特的飞行能力和有效的觅食策略而闻名,它们能够在不同的环境中快速找到食物来…

uniapp+vue2 实现Android设备禁止截屏和录屏

开发背景:项目开发需要实现安卓和ios设备禁止用户截屏录屏,目前只找到一个安卓禁用截屏录屏功能的方法,具体实现效果只在个人手机上试用过(华为nova9) 项目架构:uniappvue2版本 代码: // #ifde…

高级网页爬虫开发:Scrapy和BeautifulSoup的深度整合

引言 在互联网时代,数据的价值日益凸显。网页爬虫作为一种自动化获取网页内容的工具,广泛应用于数据挖掘、市场分析、内容聚合等领域。Scrapy是一个强大的网页爬虫框架,而BeautifulSoup则是一个灵活的HTML和XML文档解析库。本文将探讨如何将…

hive中分区与分桶的区别

过去,在学习hive的过程中学习过分桶与分区。但是,却未曾将分区与分桶做详细比较。今天,回顾skew join时涉及到了分桶这一概念,一时间无法区分出分区与分桶的区别。查阅资料,特地记录下来。 一、Hive分区 1.分区一般是…

正则化的定义

正则化 正则化是一种在机器学习中用于防止过拟合的技术。其基本思想是在模型复杂度增加的同时,通过惩罚部分参数,使得模型对训练数据的拟合变得更平滑,提高泛化能力。 优点: 防止过拟合:减少模型对训练数据噪声的敏…

Kolla-Ansible的确是不支持CentOS-Stream系列产品了

看着OpenStack最新的 C 版本出来一段时间了,想尝个鲜、用Kolla-Ansible进行容器化部署,结果嘛。。。 根据实验结果,自OpenStack Bobcat版本开始,Kolla-Ansible就适合在CentOS系列产品上部署了,通过对 Bobcat和Caracal…

【docker】部署证书过期监控系统mouday/domain-admin

证书过期了再去部署证书容易被骂,就找了一个开源的证书过期系统来部署一下 过程 官方文档:https://domain-admin.readthedocs.io/zh-cn/latest/manual/install.html#docker 直接下载镜像是超时的,切换一下文档推荐的镜像源 新建docker配置…

模拟电子技术-实验四 二极管电路仿真

实验四 二极管电路仿真 一.实验类型 验证性实验 二.实验目的 1、验证二极管的单向导电性 2、验证二极管的稳压特性。 三.实验原理 二极管的单向导电性: 四、实验内容 1、二极管参数测试仿真实验 1)仪表仿真…

IndexError: index 0 is out of bounds for axis 1 with size 0

IndexError: index 0 is out of bounds for axis 1 with size 0 目录 IndexError: index 0 is out of bounds for axis 1 with size 0 【常见模块错误】 【解决方案】 欢迎来到我的主页,我是博主英杰,211科班出身,就职于医疗科技公司&#…

Qt/C++音视频开发79-采集websocket视频流/打开ws开头的地址/音视频同步/保存到MP4文件/视频回放

一、前言 随着音视频的爆发式的增长,各种推拉流应用场景应运而生,基本上都要求各个端都能查看实时视频流,比如PC端、手机端、网页端,在网页端用websocket来接收并解码实时视频流显示,是一个非常常规的场景,单纯的http-flv模式受限于最大6个通道同时显示,一般会选择ws-f…

物联网主机 E6000:智慧应急领域的创新力量

在当今瞬息万变的世界中,突发事件和紧急情况时有发生。如何迅速、准确地应对这些挑战,保障人民生命财产安全,成为了社会发展的重要课题。而物联网主机 E6000 的出现,为智慧应急领域带来了全新的解决方案。 一、强大的性能与功能 物…

ueditor跨域问题解决

ueditor解决跨域问题 问题:1.在引用vue-ueditor-wrap后,上传图片和附件出现跨域问题,前端引用了webpack去解决跨域问题,但仍然存在跨域问题? ueditor是百度的富文本,功能较多但资料不够全,因为…

unity基础问题

1.一个列表中的UI有放大效果,用什么实现? 缩放,Layout组件可以勾选使用子级缩放,这样缩放之后也能保持间距 2.UGUI事件传递机制的冒泡机制是怎样的 事件系统从内向外遍历UI层次结构,通知父级UI元素有关该事件的信息。类…

模拟string(四)详解

目录 判断string大小关系bool operator(const string&s1,const string s2)代码 bool operator<(const string& s1, const string& s2)代码 bool operator<(const string& s1, const string& s2)代码 bool operator>(const string& s1, const …

人工智能时代的伦理与隐私保护:挑战与应对

随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;其在社会各个领域的广泛应用也带来了数据隐私侵犯、信息茧房等诸多伦理风险。尽管国外已出台系列法规来规范AI的使用&#xff0c;保护个人隐私和数据安全&#xff0c;但“大数据杀熟”、AI在医疗诊断和就业筛…