ES6 Promise/Async/Await使用

Promise应用

在工作中, 我们经常会遇到用异步请求数据, 查询一个结果, 然后把返回的参数放入到下一个执行的异步函数像这样:

javascript 复制代码
$.ajax({..., success(resp)=>{
	$.ajax({..., resp.id, success(resp)=>{
		$.ajax({..., resp.name success(resp)=>{
			//多层嵌套的情况, 看着是不是很难受
		}})
	}})
}})

当我们使用Promise后, 我们的程序就变成了这样:

javascript 复制代码
let userInfo = ()=> {
    return new Promise((resolve, reject) => {
        console.log('查询用户信息...')
        resolve('王二')
    })
}

let orderInfo = (userName)=> {
    return new Promise((resolve, reject) => {
        console.log(`查询用户${userName}的订单信息...`)
        resolve('ORDER_20230820000000001')
    })
}

userInfo().then(resp=>{
    return orderInfo(resp)
}).then(resp=>{
    console.log(resp)
})

控制台输出如下:

text 复制代码
查询用户信息...
查询用户王二的订单信息...
ORDER_20230820000000001

async/await应用

看是不是简洁很多了, 如果你不想使用这种链式调用, 也可以结合async/await来实现同步执行, 我们来稍微改一下userInfo函数, 让它模拟异步请求, 像下面这样:

javascript 复制代码
let userInfo = ()=> {
    return new Promise((resolve, reject) => {
        console.log(new Date().toLocaleString()+' 查询用户信息...')
        //这里我们模拟异步请求, 等待三秒
        setTimeout(() => {
            resolve('王二')
        }, 3000)
    })
}

let orderInfo = (userName)=> {
    return new Promise((resolve, reject) => {
        console.log(new Date().toLocaleString()+` 查询用户${userName}的订单信息...`)
        resolve('ORDER_20230820000000001')
    })
}

let main = async ()=> {
    let user = await userInfo()
    let order = await orderInfo(user);
    console.log(new Date().toLocaleString()+' '+order)
}
main()

控制台输出如下:

text 复制代码
2023/8/20 10:52:23 查询用户信息...
2023/8/20 10:52:26 查询用户王二的订单信息...
2023/8/20 10:52:26 ORDER_20230820000000001

注意看上面输出, 第一行和第二行是间隔3秒的, 说明是同步往下执行的, 这样修改之后程序是不是简洁很多呢, 对于日后维护起来也方便许多啦

异常处理

下面我们来看看如何进行异常处理, 在上面的栗子中我没有演示抛出异常和拒绝动作, 接下来看下如何处理异常和拒绝, 我们稍微改造一下代码, 像下面这样:

  1. 如果角色名称为空, 将抛出异常
  2. 如果角色等于zs, 拒绝, 无权查询
  3. 否则可以查询
javascript 复制代码
let userInfo = (roleName)=> {
    return new Promise((resolve, reject) => {
        console.log(new Date().toLocaleString() + ' 查询用户信息...')

        if (!roleName) {
            // 这里模拟抛出异常
            throw new Error('参数为空,查询异常')
        } else if (roleName === 'zs') {
            //拒绝标识
            return reject('无权查询')
        }

        //这里我们模拟异步请求, 等待三秒
        setTimeout(() => {
            resolve('王二')
        }, 3000)
    })
}

let main = async ()=> {
    try{
        //let user = await userInfo()
        let order = await orderInfo(user);
        console.log(new Date().toLocaleString()+' '+order)
    }catch (err) {
        //这里处理reject和error信息
        console.error(typeof err === 'object'?err.message:err)
    }
    
}
main()

参数为空时输出:

text 复制代码
2023/8/20 11:18:51 查询用户信息...
参数为空,查询异常

参数为zs时输出:

text 复制代码
2023/8/20 11:19:12 查询用户信息...
无权查询

参数为admin时输出:

text 复制代码
2023/8/20 11:19:46 查询用户信息...
2023/8/20 11:19:49 查询用户王二的订单信息...
2023/8/20 11:19:49 ORDER_20230820000000001

当然异常处理也可以用其他方式, 例如, 你可以在Promise提供的then和catch中处理, 像下面这样:

javascript 复制代码
userInfo('').then(resp=>{
    return orderInfo(resp)
}, err=>{
    //这里处理reject和error信息
    console.error(typeof err === 'object'?err.message:err)
})

或者像这样

javascript 复制代码
userInfo('zs').then(resp=>{
    return orderInfo(resp)
}).catch(err=>{
    //这里处理reject和error信息
    console.error(typeof err === 'object'?err.message:err)
})

怎么处理大家看自己习惯和实际需求吧

相关推荐
小小小小宇10 分钟前
前端实现合并两个已排序链表
前端
yngsqq27 分钟前
netdxf—— CAD c#二次开发之(netDxf 处理 DXF 文件)
java·前端·c#
mrsk30 分钟前
🧙‍♂️ CSS中的结界术:BFC如何拯救你的布局混乱?
前端·css·面试
jonssonyan32 分钟前
我自建服务器部署了 Next.js 全栈项目
前端
A了LONE36 分钟前
h5的底部导航栏模板
java·前端·javascript
专注VB编程开发20年37 分钟前
各版本操作系统对.NET支持情况(250707更新)
开发语言·前端·ide·vscode·.net
Zsnoin能1 小时前
AI + TailwindCSS快速搭建一个属于自己的TailwindCSS学习网站
前端·css
五号厂房1 小时前
聊一聊Javascript 中 hasOwnProperty和in操作之间的区别
前端
轻语呢喃1 小时前
JavaScript :事件循环机制的深度解析
javascript·后端
摆烂为不摆烂1 小时前
😁深入JS(六): 一文让你完全理解浏览器进程与线程
前端·javascript