js async/await
一、async
带async关键字的函数,是声明异步函数,返回值是promise对象,如果async关键字函数返回的不是promise,会自动用Promise.resolve()包装。
async function test() {
return 'test'
}
test();
返回值为 Promise {<resolved>: "test"}。
二、await
await等待右侧表达式的结果,这个结果是promise对象或者其他值。
如果它等到的不是一个 promise 对象,那 await 表达式的运算结果就是它等到的东西。
如果它等到的是一个 promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。
function test() {
return new Promise(resolve => {
setTimeout(() => resolve("test"), );
});
}
const result = await test();
console.log(result);
console.log('end')
由于test()造成的阻塞,console.log('end')会等到两秒后执行
所以为了避免造成阻塞,await 必须用在 async 函数中,async 函数调用不会造成阻塞。
function test() {
return new Promise(resolve => {
setTimeout(() => resolve("test"), );
});
}
async function test2() {
const result = await test();
console.log(result);
}
test2();
console.log('end');
先执行console.log('end'),两秒后执行console.log('test')
如果await用在普通函数中,会报错,如下:

三、async/await的执行顺序
遇到await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,继续执行await后面的代码。以下面的代码分析:
async function test1() {
console.log('start test1');
console.log(await test2());
console.log('end test1');
}
async function test2() {
console.log('test2');
return await 'return test2 value'
}
test1();
console.log('start async');
setTimeout(() => {
console.log('setTimeout');
}, );
new Promise((resolve, reject) => {
console.log('promise1');
resolve();
}).then(() => {
console.log('promise2');
});
console.log('end async');
执行的结果

· 首先执行宏任务,执行test1函数,执行console.log('statr test1')
· 遇到await,先执行右边test2中的console.log('test2'),中断了后面的代码,执行test1外面的同步代码
· 执行console.log('start async');
· 遇到setTimeout,推到到下个宏任务队列中
· 执行Promise里面的同步代码console.log('promise1')
· 运行到promise().then,发现是promise对象,推到微任务队列中
· 执行console.log('end async')
· test1外面的同步代码执行结束后,回到test1中,console.log(await test2())执行完成后返回Promise {<resolved>: "return test2 value"},是promise对象,推到微任务队列中
· 此时第一个宏任务结束,执行所有的微任务,因为微任务队列先进先出,所以先执行console.log('promise2'),后执行console.log('return test2 value')
· 执行test2完成后,后面的代码不再阻塞,执行console.log('end test1');
· 执行下个宏任务,即执行console.log('setTimeout');
补充下有关宏任务和微任务的知识
宏任务和微任务都是队列,宏任务有script、setTimeout、setInterval等,微任务有Promise.then catch finally、process.nextTick等,宏任务和微任务的关系如下:

先执行第一个宏任务,执行结束后,执行所有的微任务,然后执行下个宏任务。
四、async/await的优缺点
1. 优点
相对于promise,async/await处理 then 的调用链,代码要清晰很多,几乎和同步代码一样
2. 缺点
滥用 await 可能会导致性能问题,因为 await 会阻塞代码
五、处理reject
1. try/catch
async function fn() {
try {
await new Promise((resolve, reject) => {
setTimeout(() => {
reject('err3');
}, );
})
} catch (err){
alert(err)
}
}
fn()
2. catch
async function fn() {
await new Promise((resolve, reject) => {
setTimeout(() => {
reject('err');
}, );
})
}
fn().catch(alert)
参考:
1. https://segmentfault.com/a/1190000007535316
2. https://segmentfault.com/a/1190000017224799
3. https://www.cnblogs.com/wangziye/p/9566454.html
js async/await的更多相关文章
- js async await 终极异步解决方案
既然有了promise 为什么还要有async await ? 当然是promise 也不是完美的异步解决方案,而 async await 的写法看起来更加简单且容易理解. 回顾 Promise Pr ...
- node.js async/await 继发执行与并发执行
async/await 继发执行与并发执行,看如何控制 两个异步函数 foo bar function foo() { return new Promise((resolve, reject) =&g ...
- [转] js async await 终极异步解决方案
阅读目录 回顾 Promise async await 字面理解 async.await 如何执行 await 操作符 总结 既然有了promise 为什么还要有async await ? 当然是pr ...
- [node.js] async/await如何优雅处理异常?
node.js的世界,从callback开始,不会止于async. 所有人都在骂为什么不能完全进化,其实我感觉这就是老外的细心,为了承上.这也就是为什么async其实就是promise一样,假如不是一 ...
- 图与例解读Async/Await
JavaScript ES7的async/await语法让异步promise操作起来更方便.如果你需要从多个数据库或者接口按顺序异步获取数据,你可能最终写出一坨纠缠不清的promise与回调.然而使用 ...
- js异步编程终级解决方案 async/await
在最新的ES7(ES2017)中提出的前端异步特性:async.await. async.await是什么 async顾名思义是“异步”的意思,async用于声明一个函数是异步的.而await从字 ...
- callback vs async.js vs promise vs async / await
需求: A.依次读取 A|B|C 三个文件,如果有失败,则立即终止. B.同时读取 A|B|C 三个文件,如果有失败,则立即终止. 一.callback 需求A: let read = functio ...
- 【学习笔记】JS经典异步操作,从闭包到async/await
参考文献:王仕军——知乎专栏前端周刊 感谢作者的热心总结,本文在理解的基础上,根据自己能力水平作了一点小小的修改,在加深自己印象的同时也希望能和各位共同进步... 1. 异步与for循环 抛出一个问题 ...
- JS异步编程 (2) - Promise、Generator、async/await
JS异步编程 (2) - Promise.Generator.async/await 上篇文章我们讲了下JS异步编程的相关知识,比如什么是异步,为什么要使用异步编程以及在浏览器中JS如何实现异步的.最 ...
随机推荐
- html5制作坦克大战
全部html5都采用绘图技术完成.坦克是画出来的.(坦克,子弹,墙,水,草坪) 首先我们画出坦克. 坦克是两边两个矩形,中间一个大矩形,矩形了有一个圆,还有一根线. 画出坦克的思路是以坦克的左上角为参 ...
- java 中的拦截器和过滤器
区别: 1.拦截器是基于java的反射机制的,而过滤器是基于函数回调 2.过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 3.拦截器只能对action请求起作用,而过滤器则可以对几 ...
- artDialog 简单使用!
简介 artDialog是一个轻巧且高度兼容的javascript对话框组件,可让你的网页交互拥有桌面软件般的用户体验. 功能: 支持锁定屏幕(遮罩).模拟alert和confirm.多窗口弹出.静止 ...
- Hibernate学习---第九节:Hibernate之hql
一.Hql 入门 1.实体类: package learn.hibernate.bean; import java.util.Date; import java.util.HashSet; impor ...
- Python编程-一个小爬虫工具的实现过程
需求描述: 1,打开网站: 2,获取网站的文件内容: 3,返回保存到文件中: 这里的就用到了多线程的方法 import requests,threading,time def write_html(u ...
- hbase_学习_00_资源帖
一.官方资料 1.官网:http://hbase.apache.org/ 2.官方文档:HBase 官方文档中文版 二.apache软件下载基地 1. Apache Software Foundati ...
- ADO:游标与RecordSetPtr
一.游标的属性设置: 游标是记录集recordset中用于游动逐个查找一条记录的一种机制.查询的数据返回后,通过游标来逐条获取查询的记录. 因此在配置数据库查询方式前可配置游标的属性: rs.Curs ...
- NYOJ-求逆序数 ----------------待解决,WA
描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 现在,给你一个N个元素的序列,请你判断出它的逆序数 ...
- bzoj 2969: 矩形粉刷 概率期望
题目: 为了庆祝新的一年到来,小M决定要粉刷一个大木板.大木板实际上是一个W*H的方阵.小M得到了一个神奇的工具,这个工具只需要指定方阵中两个格子,就可以把这两格子为对角的,平行于木板边界的一个子矩形 ...
- 51nod 1686 第K大区间 二分瞎搞
题目: 定义一个区间的值为其众数出现的次数. 现给出n个数,求将所有区间的值排序后,第K大的值为多少. 题解: 答案明显单调,我们考虑二分答案. 转化为判定问题后我们需要观察到一个性质: 如果一个区间 ...