ES6系列 (05):async await
2020-12-14 22:20
796 查看
首先我们先来了解几个async基本知识点:
await命令只能用在
async函数之中,如果用在普通函数,就会报错
async函数返回的是Promise 对象
- 如果返回的是一个基本类型数据,
async
函数会先用Promise.resolve(...)
将其包装为一个Promise对象再将其返回。 - 如果无返回值,等同于直接返回
Promise.resolve()
- 如果返回的是一个Promise对象,则不做处理直接将其返回
await命令后面可跟Promise对象或者任意表达式
- 如果是Promise对象,则等待并返回该对象的结果
- 如果是表达式,则等待并返回表达式的值
错误处理
如果
await后面的Promise对象变为
rejected状态 或者 async方法抛出异常,那么整个
async函数则会中断执行,并且返回的 Promise 对象为
rejected状态
-
Promise对象变为
rejected
状态:async function getTodo() { await new Promise(function (resolve, reject) { reject('异步操作出错了') }) console.log('柏成大帅比') return '柏成' } getTodo().then(res => console.log('res',res)) .catch(err => console.log('err',err)) // err,异步操作出错了
-
async方法抛出异常:
async function getTodo() { await new Promise(function (resolve, reject) { resolve('异步操作正常') }) throw new Error('代码抛出异常') console.log('柏成大帅比') return '柏成' } getTodo().then(res => console.log('res',res)) .catch(err => console.log('err',err)) // err,Error: 代码抛出异常 // at getTodo (js012-测试.html:11)
为了防止代码异常阻塞async函数的执行,我们可以使用
try...catch方法, 如果
try方法块中Promise对象变为
rejected状态 或者 代码抛出异常,则仅仅中断
try方法块的代码执行,并不会阻塞async函数的后续代码执行
async function getTodo() { try { const val1 = await getFirstVal() const val2 = await getSecondVal() const val1 = await new Promise(function (resolve, reject) { reject('异步操作异常') }) } catch (err) { console.log(err); } console.log('柏成大帅比') return 'hello world' } getTodo().then(res => console.log(res)) .catch(err => console.log(err)) // 异步操作异常 // 柏成大帅比 // hello world
实现休眠语法
记得之前做课设要实现一个着色格子板,要看到着色的过程,如何在本次着色后暂停一秒钟再执行下一次着色代码,就采用了下面的休眠方法
// 休眠方法 function sleep(interval) { return new Promise(resolve => { setTimeout(()=> resolve(), interval); }) } // 调用休眠方法 (async function () { for(let i = 1; i <= 5; i++) { console.log(i) await sleep(1000) } })()
继发&并发
继发执行:异步操作存在先后顺序,等待上一个 await 执行完毕后,再接着下一个
async function getTodo() { const val1 = await getFirstVal() const val2 = await getSecondVal() }
并发执行:异步操作相互独立,不存在依赖关系,可以同时触发,提高执行效率
// 如没有await关键字,遇到异步操作,将其挂起无需等待异步操作结果,转而继续执行下一行代码,基本等同于同时触发 const firstPromise = getFirstVal() const secondPromise = getSecondVal() const [val1, val2] = await Promise.all([firstPromise, secondPromise]); // 或者 const [val1, val2] = await Promise.all([getFirstVal(), getSecondVal()]);
循环中的await
for语句、for/in语句、for/of语句,会继发执行(等待上一个 await 执行完毕后,再接着下一个),没有任何叼毛问题,nice!
async function getTodo(arr) { for (const item of arr) { const res = await getSomething(item); console.log(`res-${item}:`, res); } console.log('finished!'); } getTodo([1,2,3]) // res-1:... // res-2:... // res-3:... // finished!
forEach、
map,调用了callback回调函数,存在大大的副作用,强烈不建议在
forEach、
map等循环 ad8 中使用
await
async function getTodo(arr) { await arr.forEach(async item => { const res = await getSomething(item); console.log(`res-${item}:`, res); }) console.log('finished!'); } getTodo([1,2,3]) // finished! // res-2:... // res-1:... // res-3:...
从上面代码中我们可以看出两个问题
-
尽管我们在
forEach
循环之前使用了await
,但是他不会等待forEach
循环的执行,而是直接打印finished!
-
三个
getSomething()
异步操作将是并发执行,请求时间短的操作将被率先打印,和请求顺序无关
参考文档
相关文章推荐
- ES6系列文章 异步神器async-await
- ES6 Promise 和 Async/await的使用
- .Net进阶系列(14)-异步多线程(async和await)(被替换)
- ES6 async/await在项目中的应用
- ES6总结--Promise 、Generator 、Async/Await
- es6的async, await使用方法及执行机制
- javascript ES6 新特性之 Promise,ES7 async / await
- Windows 8 系列(七):使用异步API:await 和 async
- ES6 —— async 和 await
- ES6入门十一:Generator生成器、async+await、Promisify
- 前端项目中常用es6知识总结 -- Async、Await让异步美如画
- es6好用的async和await
- 【ES6】ES6 Generator——ES7 Async +Await
- ES6,用 async/await 来处理异步
- C#基础系列——异步编程初探:async和await
- Windows 8实用窍门系列:5.Windows 8弹出提示框MessageDialog与await、async关键字
- Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
- C#基础系列——异步编程初探:async和await
- 第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题 第四节:一些指令总结 定时调度系列之Quartz.Net详解 第十七节:易混淆的概念(静态和非静态、拆箱和装箱) 那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)
- Windows 8实用窍门系列:5.Windows 8弹出提示框MessageDialog与await、async关键字