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

本文详细介绍了如何使用Promise配合.then()解决回调地狱问题,以及Async和Await的概念及其在处理异步操作中的优势,特别提到了它们在处理axios网络请求返回结果的应用。
摘要由CSDN通过智能技术生成

上一篇基于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')

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

  • 40
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这个问题涉及到JavaScript中的一些异步编程相关的知识点,我会逐一解答。 1. 回调:setTimeout() 回调函数是一种常见的异步编程方式,setTimeout()函数是一个典型的例子。setTimeout()可以在指定的时间之后执行一个回调函数,用法如下: ``` setTimeout(callback, delay); ``` 其中,callback是一个回调函数,delay是一个延迟时间,单位是毫秒。当延迟时间到达时,JavaScript引擎会将回调函数加入到事件队列中,等待执行。 2. promise Promise是一种异步编程的模式,它可以解决回调函数嵌套过多的问题。Promise对象表示一个异步操作的最终完成或失败,并返回一个值。Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。当异步操作完成时,Promise会进入fulfilled状态,如果出现错误则会进入rejected状态。可以通过then()方法来注册回调函数,处理Promise对象的状态变化。 3. async/await: async/await是ES7中新增的语法,它使得异步代码的写法更加优雅。async用于声明一个异步函数,await则用于等待一个Promise对象的结果。async函数返回一个Promise对象,可以使用then()方法来注册回调函数。 例如: ``` async function show() { const result = await Promise.resolve("hello"); console.log(result); } show(); ``` 这段代码中,show()函数是一个异步函数,它等待Promise.resolve()返回的结果。当Promise对象的状态变为fulfilled时,show()函数会继续执行,并打印出"hello"。 4. fetch: fetch是一种用于发送HTTP请求的API,它返回一个Promise对象。fetch()函数接受一个URL参数,可以指定请求的地址。fetch()函数返回的Promise对象可以使用then()方法来注册回调函数,处理返回的结果。 例如: ``` fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error)); ``` 这段代码中,fetch()函数发送了一个HTTP请求,请求的地址是https://api.example.com/data。当服务器返回响应时,fetch()函数会返回一个Response对象,我们可以使用response.json()方法将响应体解析为JSON对象。然后我们可以使用then()方法来处理JSON对象。如果发生了错误,我们可以使用catch()方法来捕获异常。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值