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)
})

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

相关推荐
梨涡泥窝2 分钟前
JavaWeb——基于 Spring Boot + Vue 的图书管理系统的设计与实现
vue.js·spring boot·后端
Eric_见嘉11 分钟前
打开这个 VSC 设置「组件引用位置」和数量就都清楚了
前端·typescript·visual studio code
李高钢14 分钟前
Python Tornado 框架入门:从零搭建你的第一个异步 Web 应用
前端·python·tornado
宁风26 分钟前
JavaScript:函数体系-1
前端·javascript
mmsx34 分钟前
Android 手簿 ADB 无线调试全攻略:USB 转 WiFi 一键连接
android·前端
guwentian42 分钟前
Rolldown vs esbuild vs Webpack:Rust 打包器大战我们该怎么选
前端·webpack·rust·esbuild
特立独行的猫A1 小时前
用纯 Rust 重写 Podcastfy:把网页、PDF 和一段文字,变成一档双人对话播客
前端
oooo_z1 小时前
美股历史K线数据API接口选型指南:iTick覆盖1分钟到月线全周期
服务器·前端·javascript
今日无bug1 小时前
从 0 到 1 搭建端侧 AI 项目:DeepSeek-R1 + WebGPU + React + TS + Tailwind 全栈笔记
前端·react.js·typescript
mmsx1 小时前
MapLibre 实战 08|GPS 点漂了几百米才被发现:GCJ-02 纠偏原理与"转两次"陷阱
android·前端