什么是Async/Awaitjavascript
ES6新增了Promise函数用于简化项目代码流程。然而在使用promise时,咱们仍然要使用callback,而且并不知道程序要干什么,例如:java
function doSomething() { let i = 0; waitOneSecond() // 返回一个Promise对象
.then(() => console.log(i)); i = 5; }
最终console.log(i) 的结果是5,并非0数据库
为此,ES7引入了async函数,前面的例子能够改写这样:设计模式
async function doSomething() { let i = 0; await waitOneSecond();// 等待1秒 console.log(i); i = 5; }
这段代码片断中console.log(i)的结果是0。其中关键字await中止当前函数的执行,直到waitOneSecond()返回的promise对象状态变动为fulfilled(完成),并产生其返回值。数组
当返回的promise对象的状态变动为rejected(失败),错误信息会被 try/catch 代码块所捕获。promise
常见陷阱async
效率损失:函数
乱用async/await,可能致使低效的设计模式。例如,假设咱们想从数据库中得到一些用户他们的年龄平均。咱们会这样作的:性能
async function getUserAge(userId) { await waitOneSecond();// 等待1秒 return 7; } async function getAverageAge(userIds) { let sumOfAges = 0; let numOfUsers = userIds.length; for (let userId of userIds) { sumOfAges += await getUserAge(userId); } return sumOfAges / numOfUsers; }
显而易见,这是错误的,假设咱们有5个用户,上面的代码片断会轮训全部的用户而且等待每个单独调用数据库,因此最终整个函数的等待时间是5秒。spa
为了更好的性能,下降等待时间,修改以下:
async function getAverageAge(userIds) { let sumOfAges = 0; let numOfUsers = userIds.length;
let agesPromises = userIds.map(getUserAge);//将每一个用户对应的promise对象封装到数组中 let ages = await Promise.all(agesPromises);//使用Promise.all调用 for (let age of ages) { sumOfAges += age; } return sumOfAges / numOfUsers; }
修改以后,代码变得复杂了一些,可是全部的数据库调用,都是同时进行的。不管你有多少用户,这个方法的等待时间只须要1秒。
在使用async/await函数时,当函数体内须要使用await屡次调用外部函数而且函数返回值彼此无依赖关系时,使用Promise.all下降函数总体的等待时间。
变量污染:
当使用async函数时,会令代码更易阅读,可是他们并非真正的将你的代码变为同步,只是promise的语法糖而已,看下面这个例子
let currentUserId = 0; async function getInfoAboutUser() { currentUserId++; // 令每一个用户id均惟一
let data = await waitTenSeconds(); // 获取某些其余数据,等待时间10秒
return { id: currentUserId , data }; } async function registerUser() { let user = await getInfoAboutUser(); await storeUser(user); }
如今假设,有2个不一样的用户接连注册,getInfoAboutUser 函数将被接连执行,当10秒的等待时间结束后,2个用户的id都是相同的。
在这个例子中,咱们能够很简单的避免这个问题:
async function getInfoAboutUser() { let data = await waitTenSeconds(); // 获取某些其余数据,等待时间10秒
currentUserId++; //令每一个用户id均惟一
return { id: currentUserId }; }
结语
async/await函数的出现,极大的提升了javascript代码的可读性,可是他们并非魔法,依然有不少未知的问题等待咱们去发现。
我但愿你喜欢这篇文章,并认为它游泳。若是有其余的陷阱,或者有任何疑问,请在评论中让我知道