1.Async详解
(1)async与Generator关系
async 函数就是 Generator 函数的语法糖(使用async代替*,使用await代替yield),也不需要next()执行器手动执行,内置执行器
(2)async原理
这是个异步操作,而await写法必须写在async函数内部,await命令后面可以是一个promise对象 (当然也可以是其他数据类型,但这时async函数会立即隐式调用Promise.resolve方法将其转换为resolved状态的Pormise对象,await关键字会在内部调用then方法将resolve的值返回),运行结果可以是rejected或者resolved
。
- await表示异步,会等待await后面返回一个明确的状态才会继续执行。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
- await可以理解为promise中then方法的语法糖,将resolve的值传递出来。
- async函数会隐式地返回一个promise,该promise的reosolve值就是该函数return的值。
(3)async的优点
1.代码简洁,不需要定义多余的data变量
2.async的错误处理机制好,让try/catch可以同时处理同步和异步错误,可以使用try,catch语句来处理错误
3.当promise语句中有条件判断语句,根据返回的数据决定返回的数据应该是怎样的,这样会产生过多的return语句并且代码嵌套使可读性变差,使用async/await提高代码可读性
4.promise的catch抛出错误栈,没有给出错误发生位置的线索,然而,async/await中的错误栈会指向错误所在的函数
详细解释可以参考:https://cnodejs.org/topic/58e4914e43ee7e7106c13541
2.promise与await优雅结合的写法
因为await写法不能处理多个异步的高并发操作,导致下一个操作需等待上一个异步操作的结果,所以可以使用promise里面的all(),race()方法,来优雅的处理高并发。
???在下面哦~~~
let fn = async () => {
let loginNames = await getLoginNames();
let result = (await Promise.all(
loginNames.map(async name => {
let user = await db.collection("users").findOne({loginName: name});
return user.score > 50 ? user : null;
})
)).filter(m => m !== null);
return result;
};
项目中的另外一个例子
async getProListData () {
this.tagSetList = []
this.design = []
this.resultList = []
Indicator.open();
await Promise.all(this.proListParam.parentOrgCategoryId === '220000' ? [getProductList(this.proListParam), getBannerList()] : [getProductList(this.proListParam)]).then(result => {
Indicator.close();
if (result[0].status === 200 && result[0].data) {
this.resultList = result[0].data.resultList || []
this.tagSetList = result[0].data.tagSetList || []
} else {
Toast({ message: '请求结果错误', duration: 1500 })
Promise.reject(result[0])
}
if (this.proListParam.parentOrgCategoryId === '220000') {
if (result[1] && result[1].status === 200 && result[1].data) {
this.design = [{ banner: [] }]
this.design[0].banner = result[1].data
} else {
Toast({ message: '请求结果错误', duration: 1500 })
Promise.reject(result[1])
}
} else {
this.design = result[0].data.design || []
}
}).catch(err => {
Indicator.close();
console.log(err)
})
this.isShowTopOrder = false
}
3.promise与async的深刻理解
promise不是异步操作,只是用来包裹异步操作的容器,使多个链式操作看起来更加优雅,避免多层嵌套产生的回调地狱。要想使promise产生异步的效果,里面必须包括异步操作的代码。
async同样不是异步操作,可以理解为是用来包裹promise的容器,所以仅仅包含同步代码也是无法产生异步效果的,与promise相比,可读性更好,符合代码语义。而await是用来等待异步执行结果的,使await下面的语句延后执行,无论await后面是不是promise对象,到最后都会转化为promise对象。