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

相关文章

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Java Response返回值的最佳处理方案

《JavaResponse返回值的最佳处理方案》在开发Web应用程序时,我们经常需要通过HTTP请求从服务器获取响应数据,这些数据可以是JSON、XML、甚至是文件,本篇文章将详细解析Java中处理... 目录摘要概述核心问题:关键技术点:源码解析示例 1:使用HttpURLConnection获取Resp

Java中Switch Case多个条件处理方法举例

《Java中SwitchCase多个条件处理方法举例》Java中switch语句用于根据变量值执行不同代码块,适用于多个条件的处理,:本文主要介绍Java中SwitchCase多个条件处理的相... 目录前言基本语法处理多个条件示例1:合并相同代码的多个case示例2:通过字符串合并多个case进阶用法使用

Java实现优雅日期处理的方案详解

《Java实现优雅日期处理的方案详解》在我们的日常工作中,需要经常处理各种格式,各种类似的的日期或者时间,下面我们就来看看如何使用java处理这样的日期问题吧,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言一、日期的坑1.1 日期格式化陷阱1.2 时区转换二、优雅方案的进阶之路2.1 线程安全重构2

Python处理函数调用超时的四种方法

《Python处理函数调用超时的四种方法》在实际开发过程中,我们可能会遇到一些场景,需要对函数的执行时间进行限制,例如,当一个函数执行时间过长时,可能会导致程序卡顿、资源占用过高,因此,在某些情况下,... 目录前言func-timeout1. 安装 func-timeout2. 基本用法自定义进程subp

基于Java实现回调监听工具类

《基于Java实现回调监听工具类》这篇文章主要为大家详细介绍了如何基于Java实现一个回调监听工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录监听接口类 Listenable实际用法打印结果首先,会用到 函数式接口 Consumer, 通过这个可以解耦回调方法,下面先写一个

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St

Python中判断对象是否为空的方法

《Python中判断对象是否为空的方法》在Python开发中,判断对象是否为“空”是高频操作,但看似简单的需求却暗藏玄机,从None到空容器,从零值到自定义对象的“假值”状态,不同场景下的“空”需要精... 目录一、python中的“空”值体系二、精准判定方法对比三、常见误区解析四、进阶处理技巧五、性能优化