接上Promise()对象处理回调地狱:怎么用.then()?什么是Async、Await?

2024-03-01 22:20

本文主要是介绍接上Promise()对象处理回调地狱:怎么用.then()?什么是Async、Await?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

上一篇基于JavaScript基础的异步、同步操作,promise、.then()-CSDN博客讲了【啥是异步操作、同步操作?】然后简单讲了回调函数是啥、Promise()对象是啥、.then()函数是啥,这一篇讲讲promise()对象到底怎么配合.then()函数解决回调地狱,还有Async、Await又是啥。

一、最简单的方式了解怎么用【Promise对象配合.then()】解决回调地狱

1、首先回顾一下Promise对象配合.then()的用法,一张图看明白

2、接下来,我们找个回调地狱的例子:

假设我要依次隔1秒输出【广东省】->【阳江市】->【阳东区】->【东城镇】

先按蠢方法

这样写看得人眼睛都花了,这啥啊?老方法的.then()就是不断创建新的Promise对象,然后把resoleve()成功函数里把上一个【成功的结果】拼上【新的成功结果】传出去,传到下一个.then()函数里,依次反复,估计我讲这么多没人会看,也没人看懂,那么我们跳过

3、现在我们优化一下,怎么搞?简单理解:

1、.then()函数是怎么获取到resolve()成功函数的结果的?只要Promise对象设置了resolve()成功函数,然后Promise对象自己调用自己的.then()回调函数,这个回调函数的参数自动就接收【resolve()成功函数】的传出去的参数结果

2、那么第一步必须得有一个Promise对象,里面照上面操作设置resolve、reject函数并往里传入像输出的结果作为参数,然后在外面用Promise对象.then()输出结果

const p = new Promise(( resolve, reject ) => {resolve('成功的结果')reject(new Error('错的提示'))
})p.then(res=>{//拿到第一个‘成功的结果’
})

3、第三步重要了!!很简单,你在这个.then()函数里return一下结果,这个结果不就可以传出去给别人用了吗?然后在这个.then()后面再接一个.then()函数,刚刚return的结果就给到下一个.then()函数了,它再拿到上一个的结果,跟上自己的结果return给下一个,下下个.then()又接到它return的

p.then(res=>{return 结果
}).then(res=>{return 结果
}).then(res=>{return 结果
})
......

4、然后注意一点,我们不是简单return个【结果】就行了,你要一直用.then()函数的话,要想一想.then()是谁的函数?要Promise对象才可以调用.then()啊,而且.then()接收的结果也是来自Promise对象的resolve成功函数传出的结果,总而言之!你return的东西应该是一个【Promise对象】!!!!

你把【包含了要输出的结果】的【Promise对象】return出去,然后这个【Promise对象】调用.then(),再接着把【包含了要输出的结果】的【Promise对象】return出去

最后优化结果是这样:

代码在这:

const p = new Promise(( resolve, reject ) => {setTimeout(()=>{resolve('广东省')reject(new Error('错了'))},1000)
})p.then(res=>{return new Promise(( resolve, reject ) => {setTimeout(()=>{resolve(res + '阳江市')reject(new Error('错了'))},1000)})
}).then(res=>{return new Promise(( resolve, reject ) => {setTimeout(()=>{resolve(res + '阳东区')reject(new Error('错了'))},1000)})
}).then(res=>{return new Promise(( resolve, reject ) => {setTimeout(()=>{resolve(res + '东城镇')reject(new Error('错了'))},1000)})
}).then(res=>{console.log(res)
})

二、如果上面的你理解起来还是很头晕,那么现在来了解【Async】、【Await】是什么

上面的例子还是要一会又return,一会又.then(),哪个结果对应到哪个.then()函数,一时还真不好找,那么现在有这两个东西修改一下写法:【Async】、【Await】

【Async】:不用去查那么复杂的解释,简单理解就是【异步函数】,任何函数前面加了Async关键字,那就是一个【Async异步函数】

【Await】:Await函数就是等待一个Promise对象兑现成功或失败后,把resolve或reject的结果值返回给Await,说白了他就是.then()的替身,它来获取Promise对象的结果。用它的条件:1、必须有Promise实例   2、必须在【异步函数里】,也就是只能在【Async函数】里用

总结:它两配合起来就可以写出看着像【同步操作】写法的【异步操作】,会舒服一点

那怎么用?

1、第一步,把你要有先后次序的这些事情分别写在不同的函数里,然后这些函数要这些事情、结果输出,就要return一个包含这些结果的Promise对象,这样await就可以调用并获得这些函数结果

function A(){return new Promise(( resolve, reject ) => {setTimeout(()=>{resolve('广东省')reject(new Error('错了'))},1000)})
}
function B(){return new Promise(( resolve, reject ) => {setTimeout(()=>{resolve('阳江市')reject(new Error('错了'))},1000)})
}
function C(){return new Promise(( resolve, reject ) => {setTimeout(()=>{resolve('阳东区')reject(new Error('错了'))},1000)})
}
function D(){return new Promise(( resolve, reject ) => {setTimeout(()=>{resolve('东城镇')reject(new Error('错了'))},1000)})
}

2、第二步,因为await函数需要在【异步函数】里,那么async就是异步函数,那就是用async声明的一个函数包住await函数就行了,最后别忘了调用执行这个async函数

async function fn(){const res = await A()console.log(res)const resB = await B()console.log(resB)const resC = await C()console.log(resC)const resD = await D()console.log(resD)
}//最后别忘了调用执行这个async函数,上面只是声明函数
fn()

现在你看,是不是能很清晰的看出哪个结果来自哪个函数了

三、这两玩意广泛用于获取axios网络请求返回的结果

axios和Promise

学过ajax的知道axios库是一个发送网络请求的HTTP客户端,它的底层原理就是基于在一个【Promise对象】里创建一个【XMLHttpRequest对象】,然后把传给axios库的服务器网址参数传给自己函数里的【Promise对象】的【XMLHttpRequest对象】,进行发送请求,然后把请求成功的结果或失败的结果,通过【Promise对象】return出去

这里给大伙看一个自己手动创建一个本地axios库的例子方便大家理解

function MyAxios(config){return new Promise(( resolve , reject ) => {//创建XMLHttpRequest()对象来发送请求const xhr = new XMLHttpRequest()//这里直接用对象的属性来open(), “对象形参.method”如果没有设置就是undefined,那么就自动选'请求方式',然后url也用下面调用时传的对象参数的属性就行xhr.open(config.method || 'get' , config.url)xhr.addEventListener('loadend',function(){//通过状态码来判断是成功还剩失败,状态码一般200多的就是成功,所以只要>=200 && < 300就行if(xhr.status >= 200 && xhr.status < 300){resolve(JSON.parse(xhr.response))//请求成功结果}else{reject(new Error(xhr.response))//请求失败结果}})xhr.send()})
}MyAxios({url: 'https://hmajax.itheima.net/api/province',            
}).then(res => {console.log(res)
}).catch(err => {document.querySelector('.myP').innerHTML = err.message
})

所以我们学axios库的时候,才会用axios()库去调用.then()、.catch()函数,因为axios库函数它return的就是【Promise对象】,也就是一个【Promise对象】在用.then()、.catch()方法。

既然如此,那么用【async】和【await】也同样可以

现在我们知道axios就是基于Promise对象的,那么当使用axios发送请求时,就会返回一个Promise对象,然后【await函数】就可以等待Promise对象兑现结果之后,获取到它的成功或失败的结果,然后在搭配async函数,完美,这样就可以获得axios库返回的结果了,不用.then()和.catch()了

async function fn(value){//设一个变量接收await获取到的axios返回的网络请求结果const res = await axios({url: 'https://applet-base-api-t.itheima.net/api/translate',params: {words: value}})console.log(res)
}fn('damn')

讲完了,要是还看不懂,那你就转行吧,没希望了兄弟

这篇关于接上Promise()对象处理回调地狱:怎么用.then()?什么是Async、Await?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/764014

相关文章

解决docker目录内存不足扩容处理方案

《解决docker目录内存不足扩容处理方案》文章介绍了Docker存储目录迁移方法:因系统盘空间不足,需将Docker数据迁移到更大磁盘(如/home/docker),通过修改daemon.json配... 目录1、查看服务器所有磁盘的使用情况2、查看docker镜像和容器存储目录的空间大小3、停止dock

JavaScript对象转数组的三种方法实现

《JavaScript对象转数组的三种方法实现》本文介绍了在JavaScript中将对象转换为数组的三种实用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录方法1:使用Object.keys()和Array.map()方法2:使用Object.entr

5 种使用Python自动化处理PDF的实用方法介绍

《5种使用Python自动化处理PDF的实用方法介绍》自动化处理PDF文件已成为减少重复工作、提升工作效率的重要手段,本文将介绍五种实用方法,从内置工具到专业库,帮助你在Python中实现PDF任务... 目录使用内置库(os、subprocess)调用外部工具使用 PyPDF2 进行基本 PDF 操作使用

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

使用MapStruct实现Java对象映射的示例代码

《使用MapStruct实现Java对象映射的示例代码》本文主要介绍了使用MapStruct实现Java对象映射的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、什么是 MapStruct?二、实战演练:三步集成 MapStruct第一步:添加 Mave

Python异常处理之避免try-except滥用的3个核心原则

《Python异常处理之避免try-except滥用的3个核心原则》在Python开发中,异常处理是保证程序健壮性的关键机制,本文结合真实案例与Python核心机制,提炼出避免异常滥用的三大原则,有需... 目录一、精准打击:只捕获可预见的异常类型1.1 通用异常捕获的陷阱1.2 精准捕获的实践方案1.3

Pandas处理缺失数据的方式汇总

《Pandas处理缺失数据的方式汇总》许多教程中的数据与现实世界中的数据有很大不同,现实世界中的数据很少是干净且同质的,本文我们将讨论处理缺失数据的一些常规注意事项,了解Pandas如何表示缺失数据,... 目录缺失数据约定的权衡Pandas 中的缺失数据None 作为哨兵值NaN:缺失的数值数据Panda

C++中处理文本数据char与string的终极对比指南

《C++中处理文本数据char与string的终极对比指南》在C++编程中char和string是两种用于处理字符数据的类型,但它们在使用方式和功能上有显著的不同,:本文主要介绍C++中处理文本数... 目录1. 基本定义与本质2. 内存管理3. 操作与功能4. 性能特点5. 使用场景6. 相互转换核心区别

Python动态处理文件编码的完整指南

《Python动态处理文件编码的完整指南》在Python文件处理的高级应用中,我们经常会遇到需要动态处理文件编码的场景,本文将深入探讨Python中动态处理文件编码的技术,有需要的小伙伴可以了解下... 目录引言一、理解python的文件编码体系1.1 Python的IO层次结构1.2 编码问题的常见场景二

Java中实现对象的拷贝案例讲解

《Java中实现对象的拷贝案例讲解》Java对象拷贝分为浅拷贝(复制值及引用地址)和深拷贝(递归复制所有引用对象),常用方法包括Object.clone()、序列化及JSON转换,需处理循环引用问题,... 目录对象的拷贝简介浅拷贝和深拷贝浅拷贝深拷贝深拷贝和循环引用总结对象的拷贝简介对象的拷贝,把一个