谷粒商城实战笔记-34-前端基础-ES6-promise异步编排

文章目录

  • 一,回调地狱(Callback Hell)
  • 二,实战Promise
    • 1,场景说明
    • 2,回调地狱-传统实现
    • 3,使用Promise重构
      • 3.1 用Promise实现上述需求
      • 3.2 进一步重构

在ES6中,Promise是一个用于异步编程的重要构造,它代表了一个最终可能完成或失败的异步操作,并且具有一个最终的值。

简单的说,Promise提供了一种新的异步调用的语法,让异步调用的语法更加简洁和容易理解。

接下里,我们将以一个例子深入浅出的说清楚Promise的来龙去脉。

一,回调地狱(Callback Hell)

回调地狱也被称为金字塔之痛(Pyramid of Doom),是在使用回调函数进行异步编程时遇到的一个常见问题。

在JavaScript中,回调函数经常被用来处理异步操作的结果,如网络请求、定时器、文件I/O等。

当多个异步操作需要按顺序执行,并且每个操作依赖于前一个操作的结果时,代码中可能会出现多层嵌套的回调函数,这会导致代码结构变得非常复杂和难以维护。

例如,考虑以下伪代码:

someAsyncOperation(function(result1) {anotherAsyncOperation(result1, function(result2) {yetAnotherAsyncOperation(result2, function(result3) {// ...更多的嵌套...});});
});

在这个例子中,每个异步操作都必须在其完成后调用一个回调函数,而这个回调函数可能又会触发另一个异步操作。这种深度嵌套的结构会导致代码变得难以阅读和调试,尤其是当异步操作的数量增加时。

回调地狱的几个主要问题包括:

  • 可读性差:代码的逻辑流程不易追踪,因为控制流被分割成许多嵌套的块。
  • 难以维护:修改代码或添加新的异步操作可能需要深入到多层嵌套中,这增加了引入错误的风险。
  • 错误处理复杂:在多层嵌套中处理错误通常需要在每个回调中重复错误处理代码,这可能导致代码冗余和潜在的遗漏。

为了解决回调地狱问题,现代JavaScript引入了更好的异步编程模型,如Promises和async/await语法。这些新特性提供了一种更简洁、更线性的方式来处理异步操作,减少了代码的复杂度,同时提高了可读性和可维护性。例如,使用Promises,上面的例子可以重写为:

someAsyncOperation().then(result1 => anotherAsyncOperation(result1)).then(result2 => yetAnotherAsyncOperation(result2)).then(result3 => {// ...处理result3...}).catch(error => {// ...统一处理错误...});

或者使用async/await:

async function doOperations() {try {const result1 = await someAsyncOperation();const result2 = await anotherAsyncOperation(result1);const result3 = await yetAnotherAsyncOperation(result2);// ...处理result3...} catch (error) {// ...统一处理错误...}
}

这些替代方案极大地改善了代码的结构和可读性,使得异步编程变得更加优雅和直观。

二,实战Promise

1,场景说明

假设有这样一个需求,学生登录学校的考试系统,查询某一个的成绩。

实现这个简单的需求,要发出三次请求。

  • 第一次请求,根据用户名查询用户ID,查询成功说明可以登录
  • 第一次请求成功后,发出第二次请求,查询该用户有成绩的科目ID
  • 第二次请求成功后,发出第三次请求,根据科目ID查询成绩

假设后台的数据存储在json文件中,整个请求过程如下。

第一次请求从后台的user.json文件中查询到用户的ID为1。

// user.json:
{"id": 1,"name": "zhangsan","password": "123456"
}

第二次请求从后台的user_corse_1.json中查询到用户有成绩的课程ID为10。

// user_corse_1.json:
{"id": 10,"name": "chinese"
}

第三次请求从后台的corse_score_10.json中查询到用户课程ID成绩为90。

corse_score_10.json:
{"id": 100,"score": 90
}

在这里插入图片描述

2,回调地狱-传统实现

假设我们用JQuery的ajax实现异步请求,代码如下。

html代码完整代码如下,后续的JS演示代码都放在<script>部分。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script></head>
<body><script></script>
</body>
</html>
$.ajax({// 第一次请求url: "mock/user.json",success(data) {console.log("查询用户:", data);$.ajax({// 第二次请求url: `mock/user_corse_${data.id}.json`,success(data) {console.log("查询到课程:", data);$.ajax({// 第三次请求url: `mock/corse_score_${data.id}.json`,success(data) {console.log("查询到分数:", data);},error(error) {console.log("出现异常了:" + error);}});},error(error) {console.log("出现异常了:" + error);}});},error(error) {console.log("出现异常了:" + error);}
});

上面代码仅仅有三次回调,如果回答次数更多,嵌套的更深,导致代码难以阅读和理解,这就是所谓的回调地狱

3,使用Promise重构

3.1 用Promise实现上述需求

new Promise((resolve, reject)=>{$.ajax({url: "mock/user.json",success(data) {console.log("Promise查询用户:", data);resolve(data.id);},error(error) {console.log("Promise出现异常了:" + error);reject(error);}});}).then(id=>{return new Promise((resolve, reject)=>{$.ajax({url: `mock/user_corse_${id}.json`,success(data) {console.log("Promise查询到课程:", data);resolve(data.id);},error(error) {console.log("Promise出现异常了:" + error);reject(error);}});});}).then(id=>{return new Promise((resolve, reject)=>{$.ajax({url: `mock/corse_score_${id}.json`,success(data) {console.log("Promise查询到分数:", data);resolve(data);},error(error) {console.log("Promise出现异常了:" + error);reject(error);}});});}).then(({score})=>{console.log("Promise查询到分数:", score);})

3.2 进一步重构

下面通过抽取函数、复用代码,对上述代码进行进一步重构,使之更为简洁。

把发送请求的代码抽象为一个公共的方法,减少冗余代码,代码结构更为清晰易懂。

let sendRequest = function (url, params) { return new Promise((resolve, reject) => {$.ajax({url: url,type: "GET",data: params,success(result) {resolve(result);},error(error) {reject(error);}});})
}

于是代码可以重构为:


var sendRequest = function (url, params) {return new Promise((resolve, reject) => {$.ajax({url: url,type: "GET",data: params,success(result) {console.log(result);resolve(result.id);},error(error) {reject(error);}});})}sendRequest("mock/user.json").then(id => {console.log("Promise111查询到id:", id);return sendRequest(`mock/user_corse_${id}.json`);}).then(id => {console.log("Promise1113301查询到id: " + id);return sendRequest(`mock/corse_score_${id}.json`);}).then(({ score }) => {console.log("Promise222查询到分数:", score);})

经过重构后的代码明显变得简洁易读的多,代码的编写更加符合人脑习惯的流式思考方式。

当然,Promise也是对异步回调的封装,使用起来确实要简单多了,但也增加了理解难度,需要对Promise有一定的熟悉度,否则也是很难理解的,这就要求我们多写多思考。

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

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

相关文章

网络安全-内网安全加固方案

内网接入限制(MAC地址白名单) 只允许信任设备接入内网&#xff0c;且每次自动获取的IP地址不变(后续就可根据IP地址控制访问权限) 开启DHCP服务根据MAC地址静态分配固定IP地址 只允许可信的DHCP服务器分配IP地址(防止私建DHCP服务器) DHCP Snooping 信…

在Vue中,子组件向父组件传递数据

在Vue中&#xff0c;子组件向父组件传递数据通常通过两种方式实现&#xff1a;事件和回调函数。这两种方式允许子组件与其父组件进行通信&#xff0c;传递数据或触发特定的行为。 1. 通过事件传递数据 子组件可以通过触发自定义事件&#xff0c;并将数据作为事件的参数来向父组…

电脑案件冲突问题

一.故障展示 有一天我打开了电脑,发现3这个数字按键一直在输入,拔了外界的键盘,他这个按键还是会冲突 ,就如同上面的图一样 ,可能是电脑内部的键位进了灰卡住了什么东西导致的,于是我果断就电脑上的按键给扣下来了,扣的时候不知道里面的结构非常的谨慎,所以没导致里面的结构被损…

C#开发:Git的安装和使用

一、安装git 二、如何克隆代码&#xff1f; 1.找到某个本地目录&#xff0c;右键-gitbash 2. 输入以下代码&#xff08;红色是地址&#xff0c;在gitlab获取或联系管理员获取&#xff0c;下图为复制地址&#xff09;&#xff1a; git clone http://xxxxxxxxx.git 输入帐号和令…

【公益案例展】中国电信安全大模型——锻造安全行业能量转化的高性能引擎...

‍ 电信安全公益案例 本项目案例由电信安全投递并参与数据猿与上海大数据联盟联合推出的 #榜样的力量# 《2024中国数智产业最具社会责任感企业》榜单/奖项评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 以GPT系列为代表的大模型技术&#xff0c;展现了人工智能技术与应…

深度学习中的FLOPs补充

学习了博主的介绍&#xff08;深度学习中的FLOPs介绍及计算(注意区分FLOPS)-CSDN博客&#xff09;后&#xff0c;对我不理解的内容做了一点补充。 链接放到下边啦 https://blog.csdn.net/qq_41834400/article/details/120283103 FLOPs&#xff1a;注意s小写&#xff0c;是floa…

.Net Core 微服务之Consul(二)-集群搭建

引言: 集合上一期.Net Core 微服务之Consul(一)(.Net Core 微服务之Consul(一)-CSDN博客) 。 目录 一、 Consul集群搭建 1. 高可用 1.1 高可用性概念 1.2 高可用集群的基本原理 1.3 高可用集群的架构设计 1.3.1 主从复制架构 1.3.2 共享存储架构 1.3.3 负载均衡…

小程序字体图标使用iconfont 阿里巴巴矢量图

打开链接 iconfont官网进入 素材库-官方图标库中 挑选 适合的 字体图标 放到购物车点击 导航栏 中 购物车 图标把选中的 图标 添加至项目 然后在我的项目中 找到 项目 点击 【查看在线链接】 点击 图中 【暂无代码&#xff0c;点此生成】 生成 css 文件链接点击 css 打开 css 文…

OBD诊断(ISO15031) 06服务

文章目录 功能简介ISO 9141-2、ISO 14230-4和SAE J1850的诊断服务定义1、请求特定监控系统的车载监控测试结果请求消息定义&#xff08;读取支持的TID&#xff09;2、请求特定监控系统响应消息定义的车载监控测试结果&#xff08;报告支持的TID&#xff09;3、请求特定监控系统…

每天一个数据分析题(四百二十七)- 方差分析

下面是一个方差分析表&#xff1a; 表中A&#xff0c;B&#xff0c;C&#xff0c;D&#xff0c;E五个单元格内的数据分别是&#xff08; &#xff09;。 A. 40&#xff0c;5&#xff0c;35&#xff0c;60&#xff0c;1.71 B. 40&#xff0c;5&#xff0c;35&#xff0c;60&a…

The Web3 社区 Web3 产品经理课程

概述 / 深耕区块链行业 11 年&#xff0c;和很多产品经理都打过交道&#xff1b;遇到过优秀的产品经理&#xff0c;也遇到过比较拉垮的产品经理。多年工作中&#xff0c;曾在某些团队&#xff0c;承载技术兼产品经理的角色&#xff1b;也参与过很多 Web3 外包项目&#xff0c;包…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第一篇 嵌入式Linux入门篇-第二十九章 NFS服务器的搭建和使用

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

GEO的表达矩阵的探针ID转换成基因名称教程

GEO的表达矩阵的探针ID转换成基因名称教程 前情回顾 根据GSE id自动下载处理GEO数据(必须要运行的模块) 该模块的运行窗口截图 该模块的教程 知乎地址&#xff1a;根据GEO的GSE数据集编号自动下载和处理GEO数据教程: https://zhuanlan.zhihu.com/p/708053447 该根据GSE id…

大模型最新黑书:基于GPT-3、ChatGPT、GPT-4等Transformer架构的自然语言处理 PDF

今天给大家推荐一本丹尼斯罗斯曼(Denis Rothman)编写的关于大语言模型&#xff08;LLM&#xff09;权威教程<<大模型应用解决方案> 基于GPT-3、ChatGPT、GPT-4等Transformer架构的自然语言处理>&#xff01;Google工程总监Antonio Gulli作序&#xff0c;这含金量不…

观察者模式的实现

引言&#xff1a;观察者模式——程序中的“通信兵” 在现代战争中&#xff0c;通信是胜利的关键。信息力以网络、数据、算法、算力等为底层支撑&#xff0c;在现代战争中不断推动感知、决策、指控等各环节产生量变与质变。在软件架构中&#xff0c;观察者模式扮演着类似的角色…

最小二乘算法的解

最小二乘法&#xff08;Least Squares&#xff09;是一种用于寻找线性回归模型的最佳拟合直线的标准方法。它通过最小化数据点与拟合直线之间的平方差来找到最佳拟合的线性模型。 线性回归模型 假设我们有一组数据点 (xi,yi)&#xff0c;线性回归模型的目标是找到系数 w 和截…

css预编译器--sass

Sass Sass 提供了 变量&#xff08;variables&#xff09;、嵌套规则&#xff08;nested rules&#xff09;、 混合&#xff08;mixins&#xff09;、 函数&#xff08;functions&#xff09;&#xff0c;目前我使用最多的还是变量和嵌套规则&#xff0c;貌似目前css也支持嵌套…

2024年高职物联网实验室建设及物联网实训平台整体解决方案

随着物联网技术的蓬勃发展&#xff0c;其在各行业的应用日益广泛&#xff0c;对具备物联网专业技能的高素质人才需求也急剧增加。为了满足这一市场需求&#xff0c;高职院校作为技能型人才培养的重要阵地&#xff0c;亟需加强物联网专业的建设。本文旨在提出《2024年高职物联网…

一个开源完全免费的无损视频或音频的剪切/裁剪/分割/截取和视频合并工具

大家好&#xff0c;今天给大家分享一款致力于成为顶尖跨平台FFmpeg图形用户界面应用的软件工具LosslessCut。 LosslessCut是一款致力于成为顶尖跨平台FFmpeg图形用户界面应用的软件工具&#xff0c;专为实现对视频、音频、字幕以及其他相关媒体资产的超高速无损编辑而精心打造。…

【邀请函】庭田科技邀您第五届中国国际复合材料科技大会

第五届中国国际复合材料科技大会暨第七届国际复合材料产业创新成果技术展示&#xff08;ICIE7-新疆&#xff09;将于7月25-27日在新疆乌鲁木齐-国际会展中心举行。上海庭田信息科技有限公司将携多款仿真模拟软件亮相本次大会&#xff0c;诚挚欢迎各位到场咨询了解&#xff01; …