接上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

相关文章

MySql死锁怎么排查的方法实现

《MySql死锁怎么排查的方法实现》本文主要介绍了MySql死锁怎么排查的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录前言一、死锁排查方法1. 查看死锁日志方法 1:启用死锁日志输出方法 2:检查 mysql 错误

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

Rsnapshot怎么用? 基于Rsync的强大Linux备份工具使用指南

《Rsnapshot怎么用?基于Rsync的强大Linux备份工具使用指南》Rsnapshot不仅可以备份本地文件,还能通过SSH备份远程文件,接下来详细介绍如何安装、配置和使用Rsnaps... Rsnapshot 是一款开源的文件系统快照工具。它结合了 Rsync 和 SSH 的能力,可以帮助你在 li

Spring Boot 整合 ShedLock 处理定时任务重复执行的问题小结

《SpringBoot整合ShedLock处理定时任务重复执行的问题小结》ShedLock是解决分布式系统中定时任务重复执行问题的Java库,通过在数据库中加锁,确保只有一个节点在指定时间执行... 目录前言什么是 ShedLock?ShedLock 的工作原理:定时任务重复执行China编程的问题使用 Shed

一文详解Java Condition的await和signal等待通知机制

《一文详解JavaCondition的await和signal等待通知机制》这篇文章主要为大家详细介绍了JavaCondition的await和signal等待通知机制的相关知识,文中的示例代码讲... 目录1. Condition的核心方法2. 使用场景与优势3. 使用流程与规范基本模板生产者-消费者示例

Redis如何使用zset处理排行榜和计数问题

《Redis如何使用zset处理排行榜和计数问题》Redis的ZSET数据结构非常适合处理排行榜和计数问题,它可以在高并发的点赞业务中高效地管理点赞的排名,并且由于ZSET的排序特性,可以轻松实现根据... 目录Redis使用zset处理排行榜和计数业务逻辑ZSET 数据结构优化高并发的点赞操作ZSET 结

微服务架构之使用RabbitMQ进行异步处理方式

《微服务架构之使用RabbitMQ进行异步处理方式》本文介绍了RabbitMQ的基本概念、异步调用处理逻辑、RabbitMQ的基本使用方法以及在SpringBoot项目中使用RabbitMQ解决高并发... 目录一.什么是RabbitMQ?二.异步调用处理逻辑:三.RabbitMQ的基本使用1.安装2.架构

电脑密码怎么设置? 一文读懂电脑密码的详细指南

《电脑密码怎么设置?一文读懂电脑密码的详细指南》为了保护个人隐私和数据安全,设置电脑密码显得尤为重要,那么,如何在电脑上设置密码呢?详细请看下文介绍... 设置电脑密码是保护个人隐私、数据安全以及系统安全的重要措施,下面以Windows 11系统为例,跟大家分享一下设置电脑密码的具体办php法。Windo

JSON字符串转成java的Map对象详细步骤

《JSON字符串转成java的Map对象详细步骤》:本文主要介绍如何将JSON字符串转换为Java对象的步骤,包括定义Element类、使用Jackson库解析JSON和添加依赖,文中通过代码介绍... 目录步骤 1: 定义 Element 类步骤 2: 使用 Jackson 库解析 jsON步骤 3: 添