promise与async/await解析

问题引入

什么是回调地狱

回调函数中嵌套回调函数的情况就叫做回调地狱。回调地狱就是为是实现代码顺序执行而出现的一种操作。

实例

setTimeout(()=>{
    console.log('这是第一步')
    setTimeout(()=>{
        console.log('这是第二步');
        setTimeout(()=>{
            console.log('这是第三步');
        },1000)
    },2000)
},3000)

在这里插入图片描述上面代码看起来没有什么问题,但是如果回调函数的结构十分复杂,那么层层嵌套就会让代码的结构不清晰。

回调地狱产生的问题

嵌套层次很深,可读性差,难以维护
无法正常使用return 和throw
无法正常检索堆栈信息
多个回调之间难以建立联系

解决回调地狱的方法

1、promise

2、async/await

Promise

什么是promise

1、Promise是js中的一个原生对象,是一种异步编程的解决方案,可以替换掉传统的回调函数解决方案。
2、它通过引入一个回调,避免更多的回调.
简单说Promise就是一个容器,里面保存着某个未来才会结束的事件 (通常是一个异步操作)的结果。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。

promise实现

Promise有3个状态:pending(初始),resloved(成功),rejected(失败)
通过new 可以创建一个Promise实例对象。
用法:
A、构造函数有两个参数:resloved和rejected,都是回调函数
B、resloved函数:将Promise对象的状态从“未完成”变成“成功”(即从Pending变为Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去
C、rejected函数:在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
E、.then():接收resloved函数传递过来的信息
F、.catch():接收rejected函数传递过来的信息
Promise的链式编程可以保证代码的执行顺序,前提是每一次在then做完处理后,一定要return一个Promise对象,这样才能在下一次then时接收到数据。

function fun(str){
    //创建promise对象
    let promise = new Promise((resolve,reject)=>{
        var flag = true;
        setTimeout(()=>{
            if(flag){//模拟异步调用成功
                resolve(str);//将成功的信息传递出去
            }else{//模拟异步调用失败
                reject('error')//将失败的信息传递出去
            }
        })
    })
    return promise;
}
fun('这是第一步').then((data)=>{
    console.log(data);
    return fun('这是第二步')
}).then((data)=>{
    console.log(data);
    return fun('这是第三步')
}).then((data)=>{
    console.log(data)
}).catch((data)=>{
    console.log(data)
})

在这里插入图片描述

Promise–all的用法

Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。用Promise.all来执行,all接收一个数组参数,里面的值最终都返回Promise对象。

function getWidth() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(10)
        },1000)
    })
}
function getHeight() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(20)
        },1000)
    })
}
Promise.all([getWidth(),getHeight()]).then((data)=>{
    console.log(data);
})

在这里插入图片描述

Promise–race的用法

顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([f1,f2,f3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

function getWidth() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(10)
        },2000)
    })
}
function getHeight() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(20)
        },1000)
    })
}
function getLength() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(30)
        },3000)
    })
}
Promise.race([getWidth(),getHeight(),getLength()]).then((data)=>{
    console.log(data);
})

在这里插入图片描述

async/await

Promise虽然跳出了异步嵌套的怪圈,用链式表达更加清晰,但是我们也发现如果有大量的异步请求的时候,流程复杂的情况下,会发现充满了屏幕的then,看起来非常吃力。

使用async/await基本规则

await关键字只能在使用async定义的函数中使用
​await后面可以直接跟一个 Promise实例对象(可以跟任何表达式,更多的是跟一个返回Promise对象的表达式)
await函数不能单独使用
await可以直接拿到Promise中resolve中的数据。

function fun(str){
    //创建promise对象
    let promise = new Promise((resolve,reject)=>{
        var flag = true;
        setTimeout(()=>{
            if(flag){//模拟异步调用成功
                resolve(str);//将成功的信息传递出去
            }else{//模拟异步调用失败
                reject('error')//将失败的信息传递出去
            }
        })
    })
    return promise;
}
//封装一个执行上述任务的async函数
async function test(){
    let res1 = await fun('这是第一步')//await直接拿到fun函数返回的promise数据
    let res2 = await fun('这是第二步')
    let res3 = await fun('这是第三步')
    console.log(res1,res2,res3);
}
test();

在这里插入图片描述

捕捉错误

await等待的虽然是promise对象,但不必写.then(..),直接可以得到返回值。
既然.then(…)不用写了,那么.catch(..)也不用写,可以直接用标准的try…catch语法捕捉错误。

function fun(str){
    //创建promise对象
    let promise = new Promise((resolve,reject)=>{
        var flag = false;
        setTimeout(()=>{
            if(flag){//模拟异步调用成功
                resolve(str);//将成功的信息传递出去
            }else{//模拟异步调用失败
                reject('error')//将失败的信息传递出去
            }
        })
    })
    return promise;
}

async function test(){
    try{
        let tes = await fun('err')
        console.log(tes);
    }catch(err){
        console.log(err);
    }
}
test();

在这里插入图片描述

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力做一只合格的前端攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值